6大設計原則之依賴倒置原則

基本概念

依賴倒置原則(Dependence Inversion Principle,DIP)

 

High level modules should not depend upon low level modules.Both should depend upon

abstractions.Abstractions should not depend upon details.Details should depend upon abstractions.

 

翻譯後的含義有如下三條

 

● 高層模塊不應該依賴低層模塊,兩者都應該依賴其抽象;

● 抽象不應該依賴細節;

● 細節應該依賴抽象。

 

解釋一下

高層模塊,原子邏輯的再組裝就是高層模塊

底層模塊,每一個邏輯的實現是由原子邏輯組成的,不可分割的原子邏輯即爲底層模塊

抽象,java語言中的接口和抽象類

細節,java語言中的實現類

依賴,類與接口、抽象類的關聯

 

此原則在java中的表現

 

● 模塊間的依賴通過抽象發生,實現類之間不發生直接的依賴關係,其依賴關係是通過接口或抽象類產生的;

● 接口或抽象類不依賴於實現類;

● 實現類依賴接口或抽象類。

 

依賴倒置原則的優點

 

●可以減少類間的耦合性;

●提高系統的穩定性;

●降低並行開發引起的風險,提高代碼的可讀性和可維護性。

 

反證法驗證依賴倒置原則的優點

 

反論題:不使用依賴倒置原則也可以減少類間的耦合性,提高系統的穩定性,降低並行開發引起的風險,提高代碼的可讀性和可維護性。

 

栗子

 

 

解釋一下這個類圖,三個類,Client類與Driver類和Benz類都有關聯關係,Driver類和Benz類的關係爲組合、關聯關係,上述類圖要表達的意思是,司機駕駛奔馳汽車

 

當需求變更等其他原因時,需要司機駕駛寶馬汽車,按照上面類圖的設計,此時我們需要增加BMW類,且Driver類新增方法,此時我們很容易發現,奔馳和寶馬只是類名不同,方法應該是相同的,設計兩個類顯得冗餘,駕駛奔馳、駕駛寶馬的方法也是方法的重載,而這個重載如果對車型進行抽象,則不需要重載,此時很明顯耦合性上升了,關於穩定性,也受到了下降,因爲新增一個類原Driver類需要進行修改。

 

使用依賴倒置原則後的類圖展示

 

 

還是按例解釋一下 BMW類和Benz類實現了ICar接口,Driver類實現了IDriver接口,IDriver類和ICar接口存在依賴關係。此時如果我們再實現司機駕駛奔馳汽車或寶馬汽車,如若還要駕駛奧迪汽車呢,此時我們僅需添加細節Aodi類,這就是耦合性降低、穩定性提高帶來的,即依賴倒置原則帶來的優點

 

這裏有個注意點:在Java中,只要定義變量就必然要有類型,一個變量可以有兩種類型:表面類型和實際類型,表面類型是在定義的時候賦予的類型,實際類型是對象的類型,這裏我們僅需理解這個實際類型即可,關於這種賦予,里氏替換原則會做詳細解釋

 

未採用依賴倒置原則進行開發,並行開發會有很大風險,以上爲例,需求變更大的話,所有的類都需要多次修改,而採用依賴倒置原則,僅需處理兩個接口極其實現類,且接口的開發進度不一致時,不影響先完成的進行測試,這裏需要使用JMock工具來實現(有興趣可以瞭解,我是沒得興趣的)

 

依賴的三種寫法

 

1.構造函數傳遞依賴對象

在類中通過構造函數聲明依賴對象,按照依賴注入的說法,這種方式叫做構造函數注入

 

2.Setter方法傳遞依賴對象

在抽象中設置Setter方法聲明依賴關係,依照依賴注入的說法,這是Setter依賴注入

 

3.接口聲明依賴對象

在接口的方法中聲明依賴對象

 

如何使用依賴倒置原則

 

● 每個類儘量都有接口或抽象類,或者抽象類和接口兩者都具備

● 變量的表面類型儘量是接口或者是抽象類

● 任何類都不應該從具體類派生

● 儘量不要覆寫基類的方法

● 結合里氏替換原則使用

 

最後解釋一下爲啥叫倒置,這裏對依賴正置做個簡單實例說明,應該就好理解倒置的含義了,還是上述案例,正常思維,開奔馳車就依賴奔馳車,開寶馬就依賴寶馬車,而不是原則後的依賴接口,這種即爲依賴倒置原則。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章