《設計模式之禪》之六大設計原則中篇
- 2019 年 11 月 5 日
- 筆記
一、依賴倒置原則
1.定義
- 高層模組不應該依賴低層模組,兩者都應該依賴其抽象;
- 抽象不應該依賴細節;
- 細節應該依賴於抽象;
高層模組和低層模組容易理解,每一個邏輯的實現都是由原子邏輯組成的,不可分割的原子邏輯就是低層模組,原子邏輯的再組裝就是高層模組。
那什麼是抽象?什麼又是細節呢?
在Java語言中,抽象就是指介面或抽象類,兩者都不能直接被實例化;細節就是實現類,實現介面或者繼承抽象類而產生的類就是細節,其特點是可以直接被實例化,也就是可以加上一個關鍵字new產生一個對象。
在Java語言中的表現就是:
- 模組間的依賴通過抽象發生,實現類之間不發生直接的依賴關係,其依賴關係是通過介面或抽象產生的;
- 介面或抽象類不依賴於實現類;
- 實現類依賴介面或抽象類;
採用依賴倒置原則可以減少類間的耦合性,提高系統的穩定性,降低並行開發引起的風險,提高程式碼的可讀性和可維護性。
注意:設計是否具備穩定性,只要適當地”鬆鬆土”,觀察”設計的藍圖”是否還可以茁壯地成長就可以得出結論,穩定性較高的設計,在周圍環境頻繁變化的時候,依然可以做到”我自巋然不動”。
2.依賴的三種寫法
(1)構造函數傳遞依賴對象
在類中通過構造函數聲明依賴對象,按照依賴注入的說法,這種方式叫做構造函數注入。
(2)Setter方法傳遞依賴對象
在抽象中設置etter方法聲明依賴關係,依照依賴注入的說法,這是Setter依賴注入。
(3)介面聲明依賴對象
在介面的方法中聲明依賴對象。
3.最佳實踐
依賴倒置原則的本質就是通過抽象(介面或抽象類)使各個類或模組的實現彼此獨立,不互相影響,實現模組間的松耦合,我們怎麼在項目中使用這個規則呢?
只要遵循如下幾個規則即可:
- 每個類盡量都有介面或抽象類或者抽象類和介面兩者都具備(這是依賴倒置的基本要求,介面和抽象類都是屬於抽象的,有了抽象才可能依賴倒置);
- 變數的表面類型盡量是介面或是抽象類;
- 任何類都不應該從具體類派生;
- 盡量不要覆寫基類的方法(如果基類是一個抽象類,而且這個方法已經實現了,子類盡量不要覆寫。類間依賴的是抽象,覆寫了抽象方法,對依賴的穩定性會產生一定的影響);
- 結合里氏替換原則使用;
二、介面隔離原則
1.定義
先明確主角-介面,介面分為兩種:
- 實例介面,在Java中聲明一個類,然後用new關鍵字產生一個實例,它是對一個類型的事物的描述,這是一種介面。比如你定義Person這個類,然後使用Person zhangSan = new Person()產生了一個實例,這個實例要遵從的標準就是Person這個類,Person類就是zhangSan的介面。Java中的類也是一種介面;
- 類介面,Java中經常使用的interface關鍵字定義的介面;
那什麼是隔離?
兩種定義如下:
- 客戶端不應該依賴它不需要的介面;
- 類間的依賴關係應該建立在最小的介面上;
先說第一種定義:”客戶端不應該依賴它不需要的介面”,那依賴什麼?依賴它需要的介面,把不需要的介面剔除掉,那就需要對介面進行細化,保證其純潔性;
再看第二種定義:”類間的依賴關係應該建立在最小的介面上”,它要求是最小的介面,也是要求介面細化,介面純潔,與第一個定義如出一轍,只是一個事物的兩種不同描述。
歸納為一句話:建立單一的介面,不要建立臃腫龐大的介面(通俗的講:介面盡量細化,同時介面中的方法盡量少)。
有人可能會疑惑,這與單一職責原則不是相同嗎?
介面隔離原則和單一職責原則的審視角度是不相同的,單一職責要求的是類和介面職責單一,注重的是職責,這是業務邏輯上的劃分,二介面隔離原則要求介面的方法盡量少。
例如一個介面的職責可能包含10個方法,這10個方法都放在一個介面中,並且提供多個模組訪問,在系統外通過文檔約束”不使用的方法不要訪問”,按照單一職責原則是允許的,因為它要求”盡量使用多個專門的介面”。專門的介面指什麼?就是指提供給每個模組的都應該是單一介面,提供給幾個模組就應該有幾個介面,而不是建立一個龐大的臃腫的介面,容納所有的客戶端訪問。
2.保證介面的純潔性
介面隔離原則是對介面進行規範約束,其包含以下4層含義:
- 介面要盡量小;
- 介面要高內聚(高內聚就是提高介面、類、模組的處理能力,減少對外交互);
- 訂製服務(訂製服務就是單獨為一個個體提供優良的服務);
- 介面設計是有限度的(介面的設計粒度越小,系統越靈活,這是不爭的事實);
3.最佳實踐
介面隔離原則是對介面的定義,同時也是對類的定義,介面和類盡量使用原子介面或原子類來組裝。但是這個原子該怎麼劃分是設計模式中的一大難題,在實踐中科院根據以下幾個規則來衡量?
- 一個介面只服務於一個子模組或業務邏輯;
- 通過業務邏輯壓縮介面中的public方法,介面時常去回顧,盡量讓介面達到”滿身筋骨肉”,而不是”肥嘟嘟”的一大堆方法;
- 已經被污染了的介面,盡量去修改,若變更風險較大,則採用適配器模式進行轉化處理;
- 了解環境,拒絕盲從。每個項目或產品都有特定的環境因素,別看到大師是這樣做的你就照抄。千萬別,環境不同,介面拆分的標準就不同。深入了解業務邏輯,最好的設計就出自你的手中;
那麼怎麼才能正確地使用介面隔離原則呢?
答案是根據經驗和常識決定介面的粒度大小,介面粒度太小,導致介面數據劇增,開發人員嗆死在介面的海洋里;介面粒度太大,靈活性降低,無法提供訂製服務給整體項目帶來無法預料的風險。
怎麼準確地實踐介面隔離原則?
實踐、經驗和領域。