七大原則

程序員大本營 2021-09-18 04:19:15 阅读数:63

七大 大原

一、單一職責原則

1.概念

一個類應該只負責一項職責

如類A負責兩個不同職責,當職責1需求變更而改變A時,可能造成職責2執行錯誤,所以需要將類A的粒度分解為A1、A2

2.案例

在這裏插入圖片描述
在Vehicle的run方法中,違反了單一職責原則

解决:根據交通工具運行方法不同,分解成不同類即可

在這裏插入圖片描述

二、接口隔離原則

1.概念

客戶端不應該依賴它不需要的接口,即一個類對另一個類的依賴應該建立在最小的接口上

2.案例

接口A有五個方法和一個實現類B
類C通過接口A依賴B但只會用到3個方法1、2、3

按接口隔離原則應該這樣處理:
將接口A拆分為獨立的幾個接口,類C去和需要的接口建立依賴關系

如:
將A拆分為接口1(含方法1)、接口2(含方法2、3)、接口3(含方法4、5)
B實現接口1、接口2

三、依賴倒轉原則

1.概念

抽象不應該依賴細節;細節應該依賴抽象。
即針對接口編程,不要針對實現編程
其本質就是面向接口編程。

多數情况下,開閉原則,裏氏替換原則,依賴倒轉原則會同時出現,開閉原則是目標,裏氏替換原則是基礎,依賴倒轉是手段。

2.案例

沿用單一職責案例
在單一職責原則案例中也采用了依賴倒轉原則
不過為了更好理解依賴倒轉原則需要修改一下,增加一個Person類
在這裏插入圖片描述
在這裏插入圖片描述
當然,如果我們不遵守依賴倒轉原則,直接面向實現編程,程序也可以正常運行,但程序的靈活性、可維護性都會降低

只要理解了多態,這一原則就很容易理解了

四、裏氏替換原則

1.概念

在任何出現父類的地方,都可以用子類替代。只有這樣,基類才能够被複用,這也是開閉原則的補充。

子類可以在父類的基礎上擴展新的功能。反過來,在使用子類的地方不能使用父類,因為父類不一定具有子類的新功能。

裏氏替換原則通俗的來講就是:子類可以擴展父類的功能,但不能改變父類原有的功能。它包含以下4層含義:

1.子類可以實現父類的抽象方法,但不能覆蓋父類的非抽象方法。

2.子類中可以增加自己特有的方法。

3.當子類的方法重載父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入參數更寬松。

4.當子類的方法實現父類的抽象方法時,方法的後置條件(即方法的返回值)要比父類更嚴格。

2.案例

當出現子類方法覆蓋父類方法時,應該將原父類和子類都繼承一個更通俗的基類,即原有的繼承關系解除,采用依賴、聚合、組合等關系代替

五、開閉原則

1.概念

一個軟件實體如類、模塊和函數應該對擴展開放(提供方),對修改關閉(使用方)。

當軟件需要變化時,盡量通過擴展軟件實體的行為來實現變化,而不是修改已有的代碼來實現變化

為了滿足開閉原則,需要對系統進行抽象化設計,抽象化是開閉原則的關鍵

2.案例

在這裏插入圖片描述
在這裏插入圖片描述
當我們在提供方擴展了一個三角形時,發現使用方也需要進行大量的修改,這不符合開閉原則,改進如下:
在這裏插入圖片描述
在這裏插入圖片描述
核心就是多態

六、迪米特法則

1.概念

  • 一個對象應該對其他對象保持最少的了解
  • 類與類關系越密切,耦合度越大
  • 迪米特法則又叫最少知道原則,即一個類對自己依賴的類知道越少越好.也就是說,對於被依賴的類不管多麼複雜,都盡量將邏輯封裝在類的內部.對外除了提供public方法,不對我泄露任何信息
  • 迪米特法則還有個更簡單的定義:只與直接的朋友通信
  • 直接的朋友:每個對象都會與其他對象有耦合關系,只要兩個對象之間有耦合關系,我們就說這兩個對象之間是朋友關系.耦合的方式很多,依賴、關聯、聚合等.其中,我們稱出現成員變量,方法參數,方法返回值中的類為直接朋友,而出現在局部變量中的類不是直接的朋友.也就是說,陌生的類最好不要以局部變量的形式出現在類的內部.
  • 迪米特法則的核心是降低類之間的耦合

七、合成複用原則

1.概念

  • 盡量使用合成/聚合的方式,而不是使用繼承

在面向對象的設計裏,有兩種基本的方法可以在不同的環境中複用已有的設計和實現

  • 通過合成/聚合複用
  • 通過繼承複用

2.合成/聚合複用

由於合成或聚合可以將已有對象納入到新對象中,使之成為新對象的一部分,因此新對象可以調用已有對象的功能。這樣做的好處有

  1. 新對象存取成分對象的唯一方法是通過成分對象的接口。
  2. 這種複用是黑箱複用,因為成分對象的內部細節是新對象看不見的。(如使用接口的話,只能看到接口方法,不能看到具體哪個實現)
  3. 這種複用支持包裝。
  4. 這種複用所需的依賴較少。
  5. 每一個新的類可以將焦點集中到一個任務上。
  6. 這種複用可以再運行時間內動態進行,新對象可以動態地引用與成分對象類型相同的對象。(使用動態代理)

一般而言,如果一個角色得到了更多的責任,那麼可以使用合成/聚合關系將新的責任委派到合適的對象。當然,這種複用也有缺點。最主要的缺點就是通過這種複用建造的系統會有較多的對象需要管理。

3.繼承複用

繼承複用通過擴展一個已有對象的實現來得到新的功能,基類明顯的捕獲共同的屬性和方法,而子類通過增加新的屬性和方法來擴展超類的實現。繼承是類型的複用。

繼承複用的優點:

  1. 新的實現較為容易,因為超類的大部分功能可以通過繼承關系自動進入子類。
  2. 修改或擴展繼承而來的實現較為容易。

繼承複用的缺點:

  1. 繼承複用破壞包裝,因為繼承將超類的實現細節暴露給了子類。因為超類的內部細節常常對子類是透明的,因此這種複用是透明的複用,又叫“白箱”複用(如:點進父類可以直接看到源碼)。
  2. 如果超類的實現改變了,那麼子類的實現也不得不發生改變。因此,當一個基類發生了改變時,這種改變會傳導到一級又一級的子類,使得設計師不得不相應的改變這些子類,以適應超類的變化。
  3. 從超類繼承而來的實現是靜態的,不可能在運行時間內發生變化,因此沒有足够的靈活性。

由於繼承複用有以上的缺點,所有盡量使用合成/聚合而不是繼承來達到對實現的複用,是非常重要的設計原則。

設計原則核心思想

  1. 找出應用中可能需要變化之處,把他們獨立出來,不要和那些不需要變化的代碼混在一起
  2. 針對接口編程,而不是針對實現編程
  3. 為了交互對象之間的松耦合設計而努力
版权声明:本文为[程序員大本營]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/09/20210918041914846a.html