設(shè)計(jì)模式之依賴倒置原則

相關(guān)鏈接:
0. 設(shè)計(jì)模式之六大原則總結(jié)
1. 設(shè)計(jì)模式之單一職責(zé)原則
2. 設(shè)計(jì)模式之里式替換原則
3. 設(shè)計(jì)模式之依賴倒置原則
4. 設(shè)計(jì)模式之接口隔離原則
5. 設(shè)計(jì)模式之迪米特法則
6. 設(shè)計(jì)模式之開閉原則

1.1 定義
  • 高層模塊不應(yīng)該依賴低層模塊,二者都應(yīng)該依賴其抽象;
  • 抽象不應(yīng)該依賴細(xì)節(jié)座硕;
  • 細(xì)節(jié)應(yīng)該依賴抽象
1.2 問題由來

類 A 直接依賴類 B,假如要將類 A 改為依賴類 C 图谷,則必須通過修改類 A 的代碼來達(dá)成主之。這種場景下酵幕,類 A一般是高層模塊衬以,負(fù)責(zé)復(fù)雜的業(yè)務(wù)邏輯缓艳;類 B 和類 C 是低層模塊,負(fù)責(zé)基本的原子操作泄鹏;假如修改類 A郎任,會(huì)給程序帶來不必要的風(fēng)險(xiǎn)。

1.3 解決方案

將類 A 修改為依賴接口 Interface1备籽,類 B 和類 C 各自實(shí)現(xiàn)接口 Interface2,類 A 通過接口 Interface1 間接與類 B 或者類 C 發(fā)生聯(lián)系,則會(huì)大大降低修改類 A 的幾率车猬。

1.4 具體分析

依賴倒置原則基于這樣一個(gè)事實(shí):相對(duì)于細(xì)節(jié)的多變性霉猛,抽象的東西要穩(wěn)定的多。以抽象為基礎(chǔ)搭建起來的架構(gòu)比以細(xì)節(jié)為基礎(chǔ)搭建起來的架構(gòu)要穩(wěn)定的多珠闰。抽象指的是接口或者抽象類惜浅,細(xì)節(jié)就是具體的實(shí)現(xiàn)類,(iOS 中可以理解為抽象就是協(xié)議伏嗜,細(xì)節(jié)是實(shí)現(xiàn)該協(xié)議的實(shí)現(xiàn)類)坛悉,使用接口或者抽象類的目的是制定好規(guī)范和契約,而不去涉及任何具體的操作承绸,把展現(xiàn)細(xì)節(jié)的任務(wù)交給他們的實(shí)現(xiàn)類去完成裸影。

依賴倒置原則的核心思想是面向接口編程,達(dá)到解耦的過程军熏。

1.5 舉例說明

我們用一個(gè)例子來說明面向接口編程相對(duì)于面向?qū)崿F(xiàn)編程好在什么地方轩猩。母親給孩子講故事,只要給她一本書荡澎,她就可以照著書給孩子講故事了均践,代碼如下:

class Book : NSObject{
    func getContent() -> String {
        return "在很久很久之前....";
    }
}

class Mother : NSObject {
    func narrate(book : Book) {
        print("媽媽開始將故事");
        print(book.getContent());
    }
}

// 執(zhí)行的代碼
let mother = Mother()
mother.narrate(book: Book())

運(yùn)行結(jié)果:

媽媽開始講故事
很久很久以前有一個(gè)阿拉伯的故事……
1.6 舉例進(jìn)階

假如有一天,孩子長大了摩幔,需要了解國家大事了彤委,不是看書,而是看報(bào)紙了或衡,讓這位母親講一下報(bào)紙的新聞焦影,報(bào)紙的代碼如下:

class Newspaper : NSObject{
    func getContent() -> String {
        return "2020 年的春運(yùn)已經(jīng)開始了....";
    }
}

但是,目前來說薇宠,這位母親辦不到啊偷办,因?yàn)?Mother 類里面只有一個(gè)narrate方法,參數(shù)是Book澄港,這時(shí)椒涯,還得需要母親學(xué)習(xí)如何讀報(bào)紙(修改 Mother 類的代碼,添加方法)回梧,需要修改 Mother 才能讀废岂,但是實(shí)際上都是文字啊,Mother 再去學(xué)習(xí)狱意,學(xué)啥昂?
假如以后需求變成雜志详囤、網(wǎng)頁呢财骨?還得需要不斷的修改 Mother镐作,這顯然不是好的設(shè)計(jì)。原因就是 Mohter與 Book 之間的耦合性太高了隆箩,必須降低他們之間的耦合度才行该贾。

我們以 iOS 為例,定義一個(gè)協(xié)議:讀物捌臊,只要是可以讀的都屬于讀物:

protocol IReader {
    // 獲取讀物內(nèi)容
    func getContent() -> String;
}

Mother類和接口 IReader 之間發(fā)生依賴關(guān)系杨蛋,而 Book 和 Newspaper 都屬于讀物的范疇,他們各自都去實(shí)現(xiàn) IReader 接口理澎,這樣就符合依賴倒置原則了逞力,代碼修改為:

class Book : NSObject, IReader{
    func getContent() -> String {
        return "在很久很久之前....";
    }
}

class Newspaper : NSObject, IReader{
    func getContent() -> String {
        return "2020 年的春運(yùn)已經(jīng)開始了....";
    }
}

class Mother : NSObject {
    func narrate(reader : IReader) {
        print("媽媽開始將故事");
        print(reader.getContent());
    }
}
1.7 舉例總結(jié)

這樣修改之后,無論以后想去看網(wǎng)頁糠爬、雜志寇荧,都不需要再修改 Mother 類了。這只是一個(gè)簡單的例子秩铆,實(shí)際情況中砚亭,代表高層模塊的 Mother 類將負(fù)責(zé)完成主要的業(yè)務(wù)邏輯,一旦需要對(duì)它進(jìn)行修改殴玛,引入錯(cuò)誤的風(fēng)險(xiǎn)極大捅膘。所以遵循依賴倒置原則可以降低類之前的耦合性,提高系統(tǒng)的穩(wěn)定性滚粟,降低修改程序造成的風(fēng)險(xiǎn)寻仗。

1.8 總結(jié)

采用依賴倒置原則給多人并行開發(fā)帶來了極大的便利,比如上例中凡壤,原本 Mother 類與 Book 類直接耦合時(shí)署尤,Mother 類必須等 Book 類編碼完成后才可以進(jìn)行編碼,因?yàn)?Mother 類依賴于 Book 類亚侠,修改后的程序則可以同時(shí)開工曹体,互不影響,因?yàn)?Mother 與 Book 類之間一點(diǎn)關(guān)系也沒有硝烂。參與協(xié)作開發(fā)的人越多箕别、項(xiàng)目越龐大,采用依賴倒置原則的意義就越重大滞谢。

在實(shí)際編程時(shí)串稀,我們一般需要做到如下 3 點(diǎn):

  • 低層模塊盡量都要有抽象類或接口,或者兩者都有
  • 變量的聲明類型盡量是抽象類或接口
  • 使用繼承時(shí)遵循里式替換原則

依賴倒置原則的核心就是要我們面向接口編程狮杨,理解了面向接口編程母截,也就理解了依賴倒置。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末橄教,一起剝皮案震驚了整個(gè)濱河市清寇,隨后出現(xiàn)的幾起案子喘漏,更是在濱河造成了極大的恐慌,老刑警劉巖颗管,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陷遮,死亡現(xiàn)場離奇詭異滓走,居然都是意外死亡垦江,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門比吭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人衩藤,你說我怎么就攤上這事钱豁∏凹疲” “怎么了缝龄?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵瘸羡,是天一觀的道長额划。 經(jīng)常有香客問我帘睦,道長间狂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任鉴象,我火速辦了婚禮,結(jié)果婚禮上纺弊,老公的妹妹穿的比我還像新娘。我一直安慰自己骡男,他們只是感情好淆游,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著洞翩,像睡著了一般稽犁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上骚亿,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天已亥,我揣著相機(jī)與錄音,去河邊找鬼来屠。 笑死虑椎,一個(gè)胖子當(dāng)著我的面吹牛震鹉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捆姜,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼传趾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泥技?” 一聲冷哼從身側(cè)響起浆兰,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎珊豹,沒想到半個(gè)月后簸呈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡店茶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年蜕便,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贩幻。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轿腺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丛楚,到底是詐尸還是另有隱情族壳,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布鸯檬,位于F島的核電站决侈,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏喧务。R本人自食惡果不足惜赖歌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望功茴。 院中可真熱鬧庐冯,春花似錦、人聲如沸坎穿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玲昧。三九已至栖茉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孵延,已是汗流浹背吕漂。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尘应,地道東北人惶凝。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像思灰,于是被迫代替她去往敵國和親混滔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容