摘要:使用設計模式能夠使我們開發的程序,易維護、可拓展,可復用。但是在23個設計模式的背后,還有7個開發原則去支撐着設計模式,保證23個設計模式能夠易維護、可拓展,可復用。所以這篇文章來解開七大設計原則的神秘面紗。
本文分享自華為雲社區《對於設計模式中七大原則的理解》,作者:小小張自由--張有博。
設計模式中分別是創建型,結構型,行為型,總共有23種設計模式。設計模式是軟件開發人員在軟件開發過程中面臨的一般問題的解決方案。這些解決方案是眾多軟件開發人員經過相當長的一段時間的試驗和錯誤總結出來的。
使用設計模式能夠使我們開發的程序,易維護、可拓展,可復用。但是在23個設計模式的背后,還有7個開發原則去支撐着設計模式,保證23個設計模式能夠易維護、可拓展,可復用。所以這篇文章來解開七大設計原則的神秘面紗。
SOLID 是面向對象設計5大重要原則的首字母縮寫,當我們設計類和模塊時,遵守 SOLID 原則可以讓軟件更加健壯和穩定。(迪米特與組合/聚合是后加的)
單一職責原則(SRP:Single responsibility principle)
1.設計原則的概念:
就一個類而言,應該僅有一個引起它變化的原因。
符合單一職責原則的類具有高內聚的特性
2.詳細解釋
每一個職責都是變化的一個軸線,如果一個類有一個以上的職責,這些職責就耦合在了一起。耦 合會影響復用性。
如果單一職責原則遵守的好,當修改一個功能時,可以顯著降低對其他功能的影響。
所以要遵守單一職責原則,避免將不同職責的功能或接口寫到同一個類中,增加了耦合性。
開閉原則(OCP:Open Closed Principle)
1.設計原則的概念:
軟件實體(類、模塊、函數等)應該可以擴展,但是不可修改。
對擴展是開放的,對於更改是封閉的。
面對新需求,對程序的改動是通過增加新代碼進行的,而不是更改現有的代碼
2.詳細解釋
當軟件需要變化時,盡量通過擴展軟件實體的行為來實現變化,而不是通過修改已有的代碼來實現變化。
編程中遵循其他原則,以及使用設計模式的目的就是遵循開閉原則。
開閉原則是所有原則中最重要的原則,它是所有原則的“老大”,其他原則是服務於開閉原則的。
里氏替換原則(LSP:liskov substitution principle)
1.設計原則的概念:
子類型必須能夠替換掉他們的父類型。所有引用父類的地方必須能透明地使用其子類的對象。
只有當子類可以替換掉父類、軟件單位的功能不受影響時,父類才能真正被復用,而子類也能夠在父類的基礎上增加新的行為
正是由於里氏代換原則,才使得開放-封閉成為了可能。
由於子類型的可替換性才使得使用父類類型的模塊在無需修改的情況下就可以拓展。
2.詳細解釋
任何基類可以出現的地方,子類一定可以出現。 LSP是繼承復用的基石,只有當衍生類可以替換掉基類,軟件單位的功能不受到影響時,基類才能真正被復用,而衍生類也能夠在基類的基礎上增加新的行為。
在使用繼承時,遵循里氏替換原則,在子類中盡量不要重寫父類已經實現了的方法。
里氏替換原則告訴我們,繼承實際上讓兩個類耦合性增強了,在適當的情況下,可以通過聚合、組合、依賴來解決問題。
接口隔離原則(ISP:Interface Segregation Principle)
1.設計原則的概念:
客戶端不應該依賴它不需要的接口。一個類對另一個類的依賴應該建立在最小的接口上。
2.詳細解釋
提供盡可能小的單獨接口,而不要提供大的總接口。暴露行為讓后面的實現類知道的越少越好。
建立單一接口,不要建立龐大的接口,盡量細化接口,接口中的方法盡量少。
接口是設計時對外部設定的約定,通過分散定義多個接口,可以預防外來變更的擴散,提高系統的靈活性和可維護性。
依賴倒轉原則(DIP:Dependence Inversion Principle)
1.設計原則的概念:
A.高層模塊不應該依賴底層模塊。兩個都應該依賴抽象
B.抽象不應該依賴細節。細節應該依賴抽象。
簡單的說就是要求對抽象進行編程,不要對實現進行編程,這樣就降低了客戶與實現模塊間的耦合。
2.詳細解釋
跟面向對象的多態意思很相像。
核心思想就是面向接口編程,使用抽象的目的是制定規范,不涉及任何具體的操作,把展示細節的任務交給實現去完成。(跟里氏代換、接口隔離,有很大關系,最后都是為了要維持開閉原則)
采用依賴倒置原則可以減少類間的耦合性,提高系統的穩定性,減少並行開發引起的風險,提高代碼的可讀性和可維護性。
組合/聚合復用原則 (CARP:Combination / aggregation Reuse Principle)
1.設計原則的概念:
盡量使用組合、聚合,盡量不要使用類繼承
2.詳細解釋
合成復用原則就是指在一個新的對象里通過關聯關系(包括組合關系和聚合關系)來使用一些已有的對象,使之成為新對象的一部分;新對象通過委派調用已有對象的方法達到復用其已有功能的目的。簡言之:要盡量使用組合/聚合關系,少用繼承。
在面向對象設計中,可以通過兩種基本方法在不同的環境中復用已有的設計和實現,即通過組合/聚合關系或通過繼承。
組合/聚合復用原則可以使系統更加靈活,類與類之間的耦合度降低,一個類的變化對其他類造成的影響相對較少,因此一般首選使用組合/聚合來實現復用;其次才考慮繼承,在使用繼承時,需要嚴格遵循里氏代換原則,有效使用繼承會有助於對問題的理解,降低復雜度,而濫用繼承反而會增加系統構建和維護的難度以及系統的復雜度,因此需要慎重使用繼承復用。
迪米特法則(LOD:Law of Demeter)
1.設計原則的概念:
如果兩個類不必彼此直接通信,那么這兩個類就不應當發生直接的相互作用。如果其中一個類需要調用另一個類的某一個方法的話,可以通過第三者轉發這個調用。
2.詳細解釋
類與類之間的關系越密切,耦合度也就越來越大,只有盡量降低類與類之間的耦合才符合設計模式;對於被依賴的類來說,無論邏輯多復雜都要盡量封裝在類的內部;每個對象都會與其他對象有耦合關系,我們稱出現成員變量、方法參數、方法返回值中的類為直接的耦合依賴,而出現在局部變量中的類則不是直接耦合依賴,也就是說,不是直接耦合依賴的類最好不要作為局部變量的形式出現在類的內部。
一個對象對另一個對象知道的越少越好,即一個軟件實體應當盡可能少的與其他實體發生相互作用,在一個類里能少用多少其他類就少用多少,尤其是局部變量的依賴類,能省略盡量省略。同時如果兩個類不必彼此直接通信,那么這兩個類就不應當發生直接的相互作用。如果其中一個類需要調用另一個類的某一方法的話,可以通過第三者轉發這個調用。