設計模式的分類
總的來說,設計模式分位三大類:
- 建立型模式(5種)
工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式 - 結構型模式(7種)
介面卡模式、裝飾器模式、代理模式、外觀模式(門面模式)、橋接模式、組合模式、享元模式 - 行為型模式(11種)
策略模式、模板方法模式、觀察者模式、迭代器模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式
六大原則
總原則:開閉原則
定義:一個軟體實體應該對擴充套件開放,對修改關閉。
當一個軟體實體需要擴充套件的時候,不要去修改原有的程式碼,而是去擴充套件原有的程式碼。
開閉原則是最基礎的一個原則,六大原則都是開閉原則的具體形態。
採用開閉原則的原因:
-
避免測試複雜化:
通過擴充套件實現變化,測試只需要對新增類進行單元測試即可,只需要保證新類提供的方法正確就行。 -
提高程式碼複用性:
避免以後為了修改一個微小的缺陷或增加新功能,卻要在整個專案中到處查詢相關的程式碼逐一修改。 -
提高可維護性:
開發新功能時,擴充套件一個類往往比修改一個類更容易。
1. 單一職責原則
定義:有且僅有一個原因引起類的變更
優點:
- 類的複雜性降低
- 可讀性提高
- 易維護
- 修改類引起的風險降低
臨界點:
- 過度的劃分會使類劇增,增加系統的複雜度
2. 里氏代換原則
定義:所有引用基類的地方必須能透明地使用其子類的物件
優點:
- 提高程式碼的重用性
- 提高程式碼的可擴充性
- 提高專案的開放性
缺點:
- 記成是入侵式的,只要繼承,就有父類的屬性和方法
- 降低程式碼靈活性,子類多了父類的約束
- 增強耦合性,父類的常量/變數/方法改動時,必須考慮子類的修改
四層含義:
- 子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法。
- 子類中可以增加自己特有的方法。
- 當子類的方法過載父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入引數更寬鬆。
- 當子類的方法實現父類的抽象方法時,方法的後置條件(即方法的返回值)要比父類更嚴格。
3. 依賴倒轉原則
定義:
- 高層模組不應該依賴低層模組,兩者都要依賴其抽象(模組間的依賴通過抽象產生,實現類不直接發生依賴)
- 抽象不應該依賴細節(介面或者抽象類不依賴實現類)
- 細節可以依賴抽象(實現類依賴介面或抽象類)
處理:
- 每個類儘量都有介面或者抽象類
- 變數的表面型別儘量是介面或者抽象類
- 任何類都不應該從具體類派生
- 儘量不要複寫基類已實現的方法
- 結合里氏替換原則使用
4. 依賴倒轉原則
定義:客戶端不應該依賴不需要的介面,類之間的依賴關係應該建立在最小的介面上
四層含義:
- 介面儘量小,不要出現臃腫的介面
- 介面要高內聚
- 只提供訪問者需要的方法,每個介面中不存在子類用不到卻必須要實現的內容,可以將介面拆分
- 介面設計限度:設計粒度越小系統越靈活,結構會越複雜,可維護性降低
處理:
- 一個介面只服務一個子模組或者業務邏輯
- 儘量壓縮介面內的方法,保證都是有用的,避免臃腫
- 已被汙染的介面儘量去修改,若變更風險大,採用介面卡模式轉化處理
- 深入瞭解業務邏輯
5. 迪米特法則(最少知道原則)
定義:一個物件應該對其他物件有最小的瞭解(低耦合)
含義:
- 方法儘量不引入類中不存在的物件
- 儘量不要暴露過多public方法和非晶態public變數,儘量內斂
- 如果一個方法放在本類中,既不增加類間的關係,也不對本類產生負面影響,就可放置在本類中
總結:
核心觀念就是類間解耦,低耦合。其負面影響就是產生了大量的中轉或者跳轉類,導致系統複雜性提高,也為維護帶來了難度。需要反覆權衡,既做到結構清晰,又要高內聚低耦合。
如果一個類需要跳轉兩次以上才能訪問到另一個類,就需要想辦法重構了。
6. 合成複用原則
定義:是在一個新的物件裡面使用一些已有的物件,使其成為新物件的一部分。新物件通過委派達到複用已有功能的效果。
優點:
使用物件的合成/聚合將有助於保持每個類被封裝,並被集中在單個任務上。這樣類和整合層次會保持較小規模,並且不太可能增長為不可控制的龐然大物
缺點:
通過這種方式複用建造的系統會有較多的物件需要管理;為了能將多個不同的物件作為組合塊來使用,必須仔細地對介面進行定義