依賴反轉(zhuǎn)(依賴倒置)原則之“反轉(zhuǎn)(倒置)”

依賴反轉(zhuǎn)(倒置)原則(Dependency inversion principle,DIP)是面向?qū)ο缶幊?大原則之一。這個原則應(yīng)該是計算機開發(fā)人員必知必會的一個基本原則,但是看了網(wǎng)上很多Blog上貼的解釋(講解、理解等等),發(fā)現(xiàn)很多人對該原則的理解還是存在一定偏差的。
首先是該原則的含義,下列引用內(nèi)容來自于維基百科的依賴反轉(zhuǎn)原則詞條:

該原則指一種特定的解耦(傳統(tǒng)的依賴關(guān)系建立在高層次上,而具體的策略設(shè)置則應(yīng)用在低層次的模塊上)形式,使得高層次的模塊不依賴于低層次的模塊的實現(xiàn)細(xì)節(jié),依賴關(guān)系被顛倒(反轉(zhuǎn)),從而使得低層次模塊依賴于高層次模塊的需求抽象。該原則規(guī)定:

  1. 高層次的模塊不應(yīng)該依賴于低層次的模塊,兩者都應(yīng)該依賴于抽象接口;
  2. 抽象接口不應(yīng)該依賴于具體實現(xiàn)。而具體實現(xiàn)則應(yīng)該依賴于抽象接口。

網(wǎng)上不少的Blog都有說DIP原則,例子也是舉了若干,并且從舉例看貌似也很貼切。不過,這些Blog中基本都是在解釋依賴接口編程如何如何的好,當(dāng)然在他們舉的例子中均能體現(xiàn)出依賴接口編程的好處,這點本人沒有任何的異議,甚至Blog的行文和案例方面都沒有可挑剔的,比本人強太多了。但是,DIP中的倒置(習(xí)慣使用倒置,不習(xí)慣反轉(zhuǎn),以后均使用倒置)如何體現(xiàn)?難道依賴接口,不依賴具體實現(xiàn)就是所謂的“倒置”?顯然這里面還有“事兒”沒有說出來??戳司W(wǎng)上很多的解釋都讓人很失望,特別是在搜索引擎的第一頁給出的各個“文章”中,只有維基百科里面的解釋本人覺得算比較明確的。下面就說說所謂的“倒置”問題談?wù)勎易约旱恼J(rèn)識。

個人感覺針對依賴倒置原則,應(yīng)該是在涉及到軟件系統(tǒng)的結(jié)構(gòu)設(shè)計及實現(xiàn)時才能更好的去理解。按現(xiàn)在軟件開發(fā)的“行規(guī)”,一個復(fù)雜的系統(tǒng)必然存在高層與低層,并且,高層對象使用低層對象為其提供的“服務(wù)”來實現(xiàn)自己的業(yè)務(wù)邏輯,即所謂的高層依賴低層。但如果高層對象直接使用這些低層對象(的具體實現(xiàn)),當(dāng)業(yè)務(wù)變化,而低層的已有實現(xiàn)無法滿足高層的服務(wù)需求時,那就需要“傷筋動骨”。為了避免這樣的問題,人們提出了面向(依賴)接口編程,這樣只要接口不發(fā)生變化,低層的實現(xiàn)不會影響上層的使用。目前網(wǎng)上大多數(shù)的Blog基本都說到這里就“完結(jié)撒花”了。他們大概、或許、應(yīng)該是認(rèn)為依賴了接口就是“倒置”了??墒羌?xì)想一下,如果僅僅是依賴了接口就“撒花”,那為啥這個原則不叫“依賴接口原則”?這其中的“倒置”究竟是說啥?

按照常理,軟件劃分層也好,模塊也厚,通常都是將相同語義的元素放在一起,因此接口與其實現(xiàn)(類)應(yīng)該處于一層或模塊之中。如下圖所示(StarUML繪制,請忽略圖片中背景水印,免費的還要啥自行車?):
DIP1.png

這看似好像沒有問題,但是軟件的高層應(yīng)用可能會發(fā)生變化,即來自客戶的需求會發(fā)生變化(這是常事兒?。.?dāng)高層的應(yīng)用發(fā)生了改變,那它依賴的低層對象所提供的服務(wù)也很可能要發(fā)生變化,因為高層要完成新的業(yè)務(wù),低層要負(fù)責(zé)提供對應(yīng)的服務(wù)。那么問題來了,誰來約定這個接口提供什么樣的服務(wù)?按照前面的邏輯,接口和實現(xiàn)放在低層中,那應(yīng)該由低層提供,可是低層開發(fā)人員并不負(fù)責(zé)高層的應(yīng)用邏輯。低層應(yīng)該應(yīng)該只關(guān)心自己那點事兒,即負(fù)責(zé)響應(yīng)高層的需求,去按照需求提供實現(xiàn)服務(wù)。但現(xiàn)在接口放在低層維護,就應(yīng)該由低層的開發(fā)人員負(fù)責(zé)體現(xiàn)需求的接口的“變更”(提供新的服務(wù))。這樣會發(fā)現(xiàn)這樣的情況,即負(fù)責(zé)高層實現(xiàn)的開發(fā)人員,他們擁有需求,但無法定義描述需求的接口;負(fù)責(zé)低層的開發(fā)人員,他們不管需求,只應(yīng)提供具體實現(xiàn),卻要維護和應(yīng)用需求有關(guān)的接口。這不就出現(xiàn)了很大的矛盾嗎?


DIP2.png

因此,為了解決這樣的矛盾,人們提出將本應(yīng)放在低層的接口放在高層,低層的實現(xiàn)依賴高層提供的接口,去實現(xiàn)相應(yīng)的服務(wù)(請參見上圖所示)。本人認(rèn)為這才是DIP中“倒置”的真正含義所在。

本文分兩天抽空寫的,前一天還能不翻墻直接訪問中文的維基百科,今天不翻墻就不行了,白高興了半天。
ps:想吐槽,已無力,就這么著吧~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容