快速理解 設計模式六大原則

SuperMairo發表於2018-01-02

timg.jpg

前言:設計模式(Design pattern)是一套被反覆使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。設計模式使程式碼編制真正工程化,設計模式是軟體工程的基石,如同大廈的一塊塊磚石一樣。只有精通了設計模式,才敢說真正理解了軟體工程。可以說,設計模式是每一個架構師所必備的技能之一。想要精通設計模式,必須要先搞清楚設計模式的六大原則。

具體實現Demo:iOS設計模式四部曲(一):建立型模式 內附Demo

1、單一職責原則(Single Responsibility Principle,簡稱SRP )

  • 核心思想: 應該有且僅有一個原因引起類的變更
  • 問題描述: 假如有類Class1完成職責T1,T2,當職責T1或T2有變更需要修改時,有可能影響到該類的另外一個職責正常工作。
  • 好處: 類的複雜度降低、可讀性提高、可維護性提高、擴充套件性提高、降低了變更引起的風險。
  • 需注意: 單一職責原則提出了一個編寫程式的標準,用“職責”或“變化原因”來衡量介面或類設計得是否優良,但是“職責”和“變化原因”都是不可以度量的,因專案和環境而異。

2、里氏替換原則(Liskov Substitution Principle,簡稱LSP)

  • 核心思想: 在使用基類的的地方可以任意使用其子類,能保證子類完美替換基類。
  • 通俗來講: 只要父類能出現的地方子類就能出現。反之,父類則未必能勝任。
  • 好處: 增強程式的健壯性,即使增加了子類,原有的子類還可以繼續執行。
  • 需注意: 如果子類不能完整地實現父類的方法,或者父類的某些方法在子類中已經發生“畸變”,則建議斷開父子繼承關係 採用依賴、聚合、組合等關係代替繼承。

3、依賴倒置原則(Dependence Inversion Principle,簡稱DIP)

  • 核心思想:高層模組不應該依賴底層模組,二者都該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象;
  • 說明:高層模組就是呼叫端,低層模組就是具體實現類。抽象就是指介面或抽象類。細節就是實現類。
  • 通俗來講: 依賴倒置原則的本質就是通過抽象(介面或抽象類)使個各類或模組的實現彼此獨立,互不影響,實現模組間的鬆耦合。
  • 問題描述: 類A直接依賴類B,假如要將類A改為依賴類C,則必須通過修改類A的程式碼來達成。這種場景下,類A一般是高層模組,負責複雜的業務邏輯;類B和類C是低層模組,負責基本的原子操作;假如修改類A,會給程式帶來不必要的風險。
  • 解決方案: 將類A修改為依賴介面interface,類B和類C各自實現介面interface,類A通過介面interface間接與類B或者類C發生聯絡,則會大大降低修改類A的機率。
  • 好處:依賴倒置的好處在小型專案中很難體現出來。但在大中型專案中可以減少需求變化引起的工作量。使並行開發更友好。

4、介面隔離原則(Interface Segregation Principle,簡稱ISP)

  • 核心思想:類間的依賴關係應該建立在最小的介面上
  • 通俗來講: 建立單一介面,不要建立龐大臃腫的介面,儘量細化介面,介面中的方法儘量少。也就是說,我們要為各個類建立專用的介面,而不要試圖去建立一個很龐大的介面供所有依賴它的類去呼叫。
  • 問題描述: 類A通過介面interface依賴類B,類C通過介面interface依賴類D,如果介面interface對於類A和類B來說不是最小介面,則類B和類D必須去實現他們不需要的方法。
  • 需注意:
  • 介面儘量小,但是要有限度。對介面進行細化可以提高程式設計靈活性,但是如果過小,則會造成介面數量過多,使設計複雜化。所以一定要適度
  • 提高內聚,減少對外互動。使介面用最少的方法去完成最多的事情
  • 為依賴介面的類定製服務。只暴露給呼叫的類它需要的方法,它不需要的方法則隱藏起來。只有專注地為一個模組提供定製服務,才能建立最小的依賴關係。

5、迪米特法則(Law of Demeter,簡稱LoD)

  • 核心思想: 類間解耦。
  • 通俗來講: 一個類對自己依賴的類知道的越少越好。自從我們接觸程式設計開始,就知道了軟體程式設計的總的原則:低耦合,高內聚。無論是程式導向程式設計還是物件導向程式設計,只有使各個模組之間的耦合儘量的低,才能提高程式碼的複用率。低耦合的優點不言而喻,但是怎麼樣程式設計才能做到低耦合呢?那正是迪米特法則要去完成的。

6、開放封閉原則(Open Close Principle,簡稱OCP)

  • 核心思想: 儘量通過擴充套件軟體實體來解決需求變化,而不是通過修改已有的程式碼來完成變化
  • 通俗來講: 一個軟體產品在生命週期內,都會發生變化,既然變化是一個既定的事實,我們就應該在設計的時候儘量適應這些變化,以提高專案的穩定性和靈活性。

一句話概括: 單一職責原則告訴我們實現類要職責單一;里氏替換原則告訴我們不要破壞繼承體系;依賴倒置原則告訴我們要面向介面程式設計;介面隔離原則告訴我們在設計介面的時候要精簡單一;迪米特法則告訴我們要降低耦合。而開閉原則是總綱,他告訴我們要對擴充套件開放,對修改關閉。


總結:

最後總結一下如何去遵守這六個原則。對這六個原則的遵守並不是是和否的問題,而是多和少的問題,也就是說,我們一般不會說有沒有遵守,而是說遵守程度的多少。任何事都是過猶不及,設計模式的六個設計原則也是一樣,制定這六個原則的目的並不是要我們刻板的遵守他們,而需要根據實際情況靈活運用。對他們的遵守程度只要在一個合理的範圍內,就算是良好的設計。我們用一幅圖來說明一下。

1.png

圖中的每一條維度各代表一項原則,我們依據對這項原則的遵守程度在維度上畫一個點,則如果對這項原則遵守的合理的話,這個點應該落在紅色的同心圓內部;如果遵守的差,點將會在小圓內部;如果過度遵守,點將會落在大圓外部。一個良好的設計體現在圖中,應該是六個頂點都在同心圓中的六邊形

2.png

在上圖中,設計1、設計2屬於良好的設計,他們對六項原則的遵守程度都在合理的範圍內;設計3、設計4設計雖然有些不足,但也基本可以接受;設計5則嚴重不足,對各項原則都沒有很好的遵守;而設計6則遵守過渡了,設計5和設計6都是迫切需要重構的設計。


注: 本文大部分內容參考圖書《設計模式之禪》,把我理解到的部分整理分享出來。圖片以及一部分內容來源於網路,特別鳴謝原作者。大家對設計模式原則有什麼見解,歡迎留言交流~互相學習,互相進步~

相關文章