程序員大本營 2021-09-18 04:19:15 阅读数:63
一個類應該只負責一項職責
如類A負責兩個不同職責,當職責1需求變更而改變A時,可能造成職責2執行錯誤,所以需要將類A的粒度分解為A1、A2
在Vehicle的run方法中,違反了單一職責原則
解决:根據交通工具運行方法不同,分解成不同類即可
客戶端不應該依賴它不需要的接口,即一個類對另一個類的依賴應該建立在最小的接口上
接口A有五個方法和一個實現類B
類C通過接口A依賴B但只會用到3個方法1、2、3
按接口隔離原則應該這樣處理:
將接口A拆分為獨立的幾個接口,類C去和需要的接口建立依賴關系
如:
將A拆分為接口1(含方法1)、接口2(含方法2、3)、接口3(含方法4、5)
B實現接口1、接口2
抽象不應該依賴細節;細節應該依賴抽象。
即針對接口編程,不要針對實現編程
其本質就是面向接口編程。
多數情况下,開閉原則,裏氏替換原則,依賴倒轉原則會同時出現,開閉原則是目標,裏氏替換原則是基礎,依賴倒轉是手段。
沿用單一職責案例
在單一職責原則案例中也采用了依賴倒轉原則
不過為了更好理解依賴倒轉原則需要修改一下,增加一個Person類
當然,如果我們不遵守依賴倒轉原則,直接面向實現編程,程序也可以正常運行,但程序的靈活性、可維護性都會降低
只要理解了多態,這一原則就很容易理解了
在任何出現父類的地方,都可以用子類替代。只有這樣,基類才能够被複用,這也是開閉原則的補充。
子類可以在父類的基礎上擴展新的功能。反過來,在使用子類的地方不能使用父類,因為父類不一定具有子類的新功能。
裏氏替換原則通俗的來講就是:子類可以擴展父類的功能,但不能改變父類原有的功能。它包含以下4層含義:
1.子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法。
2.子類中可以增加自己特有的方法。
3.當子類的方法重載父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入參數更寬松。
4.當子類的方法實現父類的抽象方法時,方法的後置條件(即方法的返回值)要比父類更嚴格。
當出現子類方法覆蓋父類方法時,應該將原父類和子類都繼承一個更通俗的基類,即原有的繼承關系解除,采用依賴、聚合、組合等關系代替
一個軟件實體如類、模塊和函數應該對擴展開放(提供方),對修改關閉(使用方)。
當軟件需要變化時,盡量通過擴展軟件實體的行為來實現變化,而不是修改已有的代碼來實現變化
為了滿足開閉原則,需要對系統進行抽象化設計,抽象化是開閉原則的關鍵
當我們在提供方擴展了一個三角形時,發現使用方也需要進行大量的修改,這不符合開閉原則,改進如下:
核心就是多態
在面向對象的設計裏,有兩種基本的方法可以在不同的環境中複用已有的設計和實現
由於合成或聚合可以將已有對象納入到新對象中,使之成為新對象的一部分,因此新對象可以調用已有對象的功能。這樣做的好處有
一般而言,如果一個角色得到了更多的責任,那麼可以使用合成/聚合關系將新的責任委派到合適的對象。當然,這種複用也有缺點。最主要的缺點就是通過這種複用建造的系統會有較多的對象需要管理。
繼承複用通過擴展一個已有對象的實現來得到新的功能,基類明顯的捕獲共同的屬性和方法,而子類通過增加新的屬性和方法來擴展超類的實現。繼承是類型的複用。
繼承複用的優點:
繼承複用的缺點:
由於繼承複用有以上的缺點,所有盡量使用合成/聚合而不是繼承來達到對實現的複用,是非常重要的設計原則。
版权声明:本文为[程序員大本營]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210918041914846a.html