面向?qū)ο笤O(shè)計(jì)原則之依賴倒轉(zhuǎn)原則

如果說開閉原則是面向?qū)ο笤O(shè)計(jì)的目標(biāo)的話,那么依賴倒轉(zhuǎn)原則就是面向?qū)ο笤O(shè)計(jì)的主要實(shí)現(xiàn)機(jī)制之一湿蛔,它是系統(tǒng)抽象化的具體實(shí)現(xiàn)丁屎。依賴倒轉(zhuǎn)原則是·Robert C. Martin·在1996年為“C++Reporter”所寫的專欄Engineering Notebook的第三篇瘫筐,后來加入到他在2002年出版的經(jīng)典著作“Agile Software Development, Principles, Patterns, and Practices”一書中。依賴倒轉(zhuǎn)原則定義如下:

依賴倒轉(zhuǎn)原則(Dependency Inversion Principle, DIP):抽象不應(yīng)該依賴于細(xì)節(jié)喂链,細(xì)節(jié)應(yīng)當(dāng)依賴于抽象返十。換言之,要針對接口編程衩藤,而不是針對實(shí)現(xiàn)編程吧慢。

依賴倒轉(zhuǎn)原則要求我們在程序代碼中傳遞參數(shù)時(shí)或在關(guān)聯(lián)關(guān)系中,盡量引用層次高的抽象層類赏表,即使用接口和抽象類進(jìn)行變量類型聲明检诗、參數(shù)類型聲明、方法返回類型聲明瓢剿,以及數(shù)據(jù)類型的轉(zhuǎn)換等逢慌,而不要用具體類來做這些事情。
為了確保該原則的應(yīng)用间狂,一個(gè)具體類應(yīng)當(dāng)只實(shí)現(xiàn)接口或抽象類中聲明過的方法攻泼,而不要給出多余的方法,否則將無法調(diào)用到在子類中增加的新方法。

在引入抽象層后忙菠,系統(tǒng)將具有很好的靈活性何鸡,在程序中盡量使用抽象層進(jìn)行編程,而將具體類寫在配置文件中牛欢,這樣一來骡男,如果系統(tǒng)行為發(fā)生變化,只需要對抽象層進(jìn)行擴(kuò)展傍睹,并修改配置文件隔盛,而無須修改原有系統(tǒng)的源代碼,在不修改的情況下來擴(kuò)展系統(tǒng)的功能拾稳,滿足開閉原則的要求吮炕。

在實(shí)現(xiàn)依賴倒轉(zhuǎn)原則時(shí),我們需要針對抽象層編程访得,而將具體類的對象通過依賴注入(DependencyInjection, DI)的方式注入到其他對象中龙亲,依賴注入是指當(dāng)一個(gè)對象要與其他對象發(fā)生依賴關(guān)系時(shí),通過抽象來注入所依賴的對象震鹉。
常用的注入方式有三種俱笛,分別是:構(gòu)造注入設(shè)值注入(Setter注入)接口注入传趾。
構(gòu)造注入是指通過構(gòu)造函數(shù)來傳入具體類的對象迎膜,設(shè)值注入是指通過Setter方法來傳入具體類的對象,而接口注入是指通過在接口中聲明的業(yè)務(wù)方法來傳入具體類的對象浆兰。這些方法在定義時(shí)使用的是抽象類型磕仅,在運(yùn)行時(shí)再傳入具體類型的對象,由子類對象來覆蓋父類對象簸呈。

下面通過一個(gè)簡單實(shí)例來加深對依賴倒轉(zhuǎn)原則的理解:

Sunny軟件公司開發(fā)人員在開發(fā)某CRM系統(tǒng)時(shí)發(fā)現(xiàn):該系統(tǒng)經(jīng)常需要將存儲(chǔ)在TXT或Excel文件中的客戶信息轉(zhuǎn)存到數(shù)據(jù)庫中榕订,因此需要進(jìn)行數(shù)據(jù)格式轉(zhuǎn)換。在客戶數(shù)據(jù)操作類中將調(diào)用數(shù)據(jù)格式轉(zhuǎn)換類的方法實(shí)現(xiàn)格式轉(zhuǎn)換和數(shù)據(jù)庫插入操作蜕便,初始設(shè)計(jì)方案結(jié)構(gòu)如圖1所示:

圖1 初始設(shè)計(jì)方案結(jié)構(gòu)圖.png

在編碼實(shí)現(xiàn)圖1所示結(jié)構(gòu)時(shí)劫恒,Sunny軟件公司開發(fā)人員發(fā)現(xiàn)該設(shè)計(jì)方案存在一個(gè)非常嚴(yán)重的問題,由于每次轉(zhuǎn)換數(shù)據(jù)時(shí)數(shù)據(jù)來源不一定相同轿腺,因此需要更換數(shù)據(jù)轉(zhuǎn)換類两嘴,如有時(shí)候需要將TXTDataConvertor改為ExcelDataConvertor,此時(shí)族壳,需要修改CustomerDAO的源代碼憔辫,而且在引入并使用新的數(shù)據(jù)轉(zhuǎn)換類時(shí)也不得不修改CustomerDAO的源代碼,系統(tǒng)擴(kuò)展性較差仿荆,違反了開閉原則贰您,現(xiàn)需要對該方案進(jìn)行重構(gòu)坏平。

在本實(shí)例中,由于CustomerDAO針對具體數(shù)據(jù)轉(zhuǎn)換類編程锦亦,因此在增加新的數(shù)據(jù)轉(zhuǎn)換類或者更換數(shù)據(jù)轉(zhuǎn)換類時(shí)都不得不修改CustomerDAO的源代碼舶替。我們可以通過引入抽象數(shù)據(jù)轉(zhuǎn)換類解決該問題,在引入抽象數(shù)據(jù)轉(zhuǎn)換類DataConvertor之后孽亲,CustomerDAO針對抽象類DataConvertor編程坎穿,而將具體數(shù)據(jù)轉(zhuǎn)換類名存儲(chǔ)在配置文件中,符合依賴倒轉(zhuǎn)原則返劲。根據(jù)里氏代換原則,程序運(yùn)行時(shí)栖茉,具體數(shù)據(jù)轉(zhuǎn)換類對象將替換DataConvertor類型的對象篮绿,程序不會(huì)出現(xiàn)任何問題。更換具體數(shù)據(jù)轉(zhuǎn)換類時(shí)無須修改源代碼吕漂,只需要修改配置文件亲配;如果需要增加新的具體數(shù)據(jù)轉(zhuǎn)換類,只要將新增數(shù)據(jù)轉(zhuǎn)換類作為DataConvertor的子類并修改配置文件即可惶凝,原有代碼無須做任何修改吼虎,滿足開閉原則。重構(gòu)后的結(jié)構(gòu)如圖2所示:

圖2重構(gòu)后的結(jié)構(gòu)圖.png

在上述重構(gòu)過程中苍鲜,我們使用了開閉原則思灰、里氏代換原則和依賴倒轉(zhuǎn)原則,在大多數(shù)情況下混滔,這三個(gè)設(shè)計(jì)原則會(huì)同時(shí)出現(xiàn)洒疚,開閉原則是目標(biāo),里氏代換原則是基礎(chǔ)坯屿,依賴倒轉(zhuǎn)原則是手段油湖,它們相輔相成,相互補(bǔ)充领跛,目標(biāo)一致乏德,只是分析問題時(shí)所站角度不同而已。

文章轉(zhuǎn)載自 —— 面向?qū)ο笤O(shè)計(jì)原則之依賴倒轉(zhuǎn)原則

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吠昭,一起剝皮案震驚了整個(gè)濱河市喊括,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌怎诫,老刑警劉巖瘾晃,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異幻妓,居然都是意外死亡蹦误,警方通過查閱死者的電腦和手機(jī)劫拢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來强胰,“玉大人舱沧,你說我怎么就攤上這事∨佳螅” “怎么了熟吏?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長玄窝。 經(jīng)常有香客問我牵寺,道長,這世上最難降的妖魔是什么恩脂? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任帽氓,我火速辦了婚禮,結(jié)果婚禮上俩块,老公的妹妹穿的比我還像新娘黎休。我一直安慰自己,他們只是感情好玉凯,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布势腮。 她就那樣靜靜地躺著,像睡著了一般漫仆。 火紅的嫁衣襯著肌膚如雪捎拯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天歹啼,我揣著相機(jī)與錄音玄渗,去河邊找鬼。 笑死狸眼,一個(gè)胖子當(dāng)著我的面吹牛藤树,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拓萌,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼岁钓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了微王?” 一聲冷哼從身側(cè)響起屡限,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炕倘,沒想到半個(gè)月后钧大,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡罩旋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年啊央,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了眶诈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瓜饥,死狀恐怖逝撬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乓土,我是刑警寧澤宪潮,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站趣苏,受9級特大地震影響狡相,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜食磕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一谣光、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芬为,春花似錦、人聲如沸蟀悦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽日戈。三九已至询张,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間浙炼,已是汗流浹背份氧。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弯屈,地道東北人蜗帜。 一個(gè)月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像资厉,于是被迫代替她去往敵國和親厅缺。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350