設計模式(Design pattern)代表了最佳的實踐,通常被有經驗的物件導向的軟體開發人員所採用。設計模式是軟體開發人員在軟體開發過程中面臨的一般問題的解決方案。這些解決方案是眾多軟體開發人員經過相當長的一段時間的試驗和錯誤總結出來的。是一套被反覆使用的、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。
毫無疑問,設計模式於己於他人於系統都是多贏的,設計模式使程式碼編制真正工程化,設計模式是軟體工程的基石,如同大廈的一塊塊磚石一樣。專案中合理地運用設計模式可以完美地解決很多問題,每種模式在現實中都有相應的原理來與之對應,每種模式都描述了一個在我們周圍不斷重複發生的問題,以及該問題的核心解決方案,這也是設計模式能被廣泛應用的原因。
說明:這23種設計模式分為三大類,建立型模式、結構型模式和行為型模式。
關注類與物件之間的組合。
結構型模式主要研究的是類和物件的組合的問題。它包括兩種型別,一是類結構型模式:指的是採用繼承機制來組合實現功能;二是物件結構型模式:指的是通過組合物件的方式來實現新的功能。
關注類與物件之間的組合。
結構型模式主要研究的是類和物件的組合的問題。它包括兩種型別,一是類結構型模式:指的是採用繼承機制來組合實現功能;二是物件結構型模式:指的是通過組合物件的方式來實現新的功能。
關注物件和行為的分離
行為型模式主要討論的是在不同物件之間劃分責任和演演算法的抽象化的問題。行為型模式又分為類的行為模式和物件的行為模式兩種。
(1)SRP(Single ResponsibilitiesPrinciple)的定義:就一個類而言,應該僅有一個引起它變化的原因。簡而言之,就是功能要單一。
(2)如果一個類承擔的職責過多,就等於把這些職責耦合在一起,一個職責的變化可能會削弱或者抑制這個類完成其它職責的能力。這種耦合會導致脆弱的設計,當變化發生時,設計會遭受到意想不到的破壞。
(3)軟體設計真正要做的許多內容,就是發現職責並把那些職責相互分離。
小結:單一職責原則(SRP)可以看做是低耦合、高內聚在物件導向原則上的引申, 將職責定義為引起變化的原因,以提高內聚性來減少引起變化的原因。責任過多,引起它變化的原因就越多,這樣就會導致職責依賴,大大損傷其內聚性和耦合度。
開閉原則的意思是:對擴充套件開放,對修改關閉。在程式需要進行拓展的時候,不能去修改原有的程式碼,實現一個熱插拔的效果。簡言之,是為了使程式的擴充套件性好,易於維護和升級。想要達到這樣的效果,我們需要使用介面和抽象類,後面的具體設計中我們會提到這點。
(1)OCP(Open-ClosePrinciple)的定義:就是說軟體實體(類,方法等等)應該可以擴充套件(擴充套件可以理解為增加),但是不能在原來的方法或者類上修改,也可以這樣說,對增加程式碼開放,對修改程式碼關閉。
(2)OCP的兩個特徵:對於擴充套件(增加)是開放的,因為它不影響原來的,這是新增加的。對於修改是封閉的,如果總是修改,邏輯會越來越複雜。
小結:開放封閉原則(OCP)是物件導向設計的核心思想。遵循這個原則可以為我們物件導向的設計帶來巨大的好處:可維護(維護成本小,做管理簡單,影響最小)、可延伸(有新需求,增加就好)、可複用(不耦合,可以使用以前程式碼)、靈活性好(維護方便、簡單)。開發人員應該僅對程式中出現頻繁變化的那些部分做出抽象,但是不能過激,對應用程式中的每個部分都刻意地進行抽象同樣也不是一個好主意。拒絕不成熟的抽象和抽象本身一樣重要。
里氏代換原則是物件導向設計的基本原則之一。里氏代換原則中說,任何基礎類別可以出現的地方,子類一定可以出現。LSP 是繼承複用的基石,只有當派生類可以替換掉基礎類別,且軟體單位的功能不受到影響時,基礎類別才能真正被複用,而派生類也能夠在基礎類別的基礎上增加新的行為。里氏代換原則是對開閉原則的補充。實現開閉原則的關鍵步驟就是抽象化,而基礎類別與子類的繼承關係就是抽象化的具體實現,所以里氏代換原則是對實現抽象化的具體步驟的規範。
(1)LSP(Liskov SubstitutionPrinciple)的定義:子型別必須能夠替換掉它們的父類別型。更直白的說,LSP是實現面向介面程式設計的基礎。
小結:任何基礎類別可以出現的地方,子類一定可以出現,所以我們可以實現面向介面程式設計。LSP是繼承複用的基石,只有當子類可以替換掉基礎類別,軟體的功能不受到影響時,基礎類別才能真正被複用,而子類也能夠在基礎類別的基礎上增加新的行為。里氏代換原則是對「開-閉」原則的補充。實現「開-閉」原則的關鍵步驟就是抽象化。而基礎類別與子類的繼承關係就是抽象化的具體實現,所以里氏代換原則是對實現抽象化的具體步驟的規範。
依賴轉換原則是開閉原則的基礎,具體內容:針對介面程式設計,依賴於抽象而不依賴於具體。
(1)DIP(Dependence InversionPrinciple)的定義:抽象不應該依賴細節,細節應該依賴於抽象。簡單說就是,我們要針對介面程式設計,而不要針對實現程式設計。
(2)高層模組不應該依賴低層模組,兩個都應該依賴抽象,因為抽象是穩定的。抽象不應該依賴具體和細節,具體和細節應該依賴抽象。
小結:依賴倒置原則其實可以說是物件導向設計的標誌,如果在我們編碼的時候考慮的是面向介面程式設計,而不是簡單的功能實現,體現了抽象的穩定性,只有這樣才符合物件導向的設計。
介面隔離原則的意思是:使用多個隔離的介面,比使用單個介面要好。它還有另外一個意思是:降低類之間的耦合度。由此可見,其實設計模式就是從大型軟體架構出發、便於升級和維護的軟體設計思想,它強調降低依賴,降低耦合。
(1)介面隔離原則(Interface Segregation Principle)指的是使用多個專門的介面比使用單一的總介面要好。也就是說不要讓一個單一的介面承擔過多的職責,而應把每個職責分離到多個專門的介面中,進行介面分離。過於臃腫的介面是對介面的一種汙染。
(2)使用多個專門的介面比使用單一的總介面要好。
(3)一個類對另外一個類的依賴性應當是建立在最小的介面上的。
(4)一個介面代表一個角色,不應當將不同的角色都交給一個介面。沒有關係的介面合併在一起,形成一個臃腫的大介面,這是對角色和介面的汙染。
(5)「不應該強迫客戶依賴於它們不用的方法。介面屬於客戶,不屬於它所在的類層次結構。」這個說得很明白了,再通俗點說,不要強迫客戶使用它們不用的方法,如果強迫使用者使用它們不使用的方法,那麼這些客戶就會面臨由於這些不使用的方法的改變所帶來的改變。
小結:介面隔離原則(ISP)告訴我們,在做介面設計的時候,要儘量設計的介面功能單一,功能單一,使它變化的因素就少,這樣就更穩定,其實這體現了高內聚,低耦合的原則,這樣做也避免介面的汙染。
迪米特法則,又稱最少知道原則(Demeter Principle)。最少知道原則是指:一個實體應當儘量少地與其他實體之間發生相互作用,使得系統功能模組相對獨立。
小結:組合/聚合複用原則可以使系統更加靈活,類與類之間的耦合度降低,一個類的變化對其他類造成的影響相對較少,因此一般首選使用組合/聚合來實現複用;其次才考慮繼承,在使用繼承時,需要嚴格遵循里氏替換原則,有效使用繼承會有助於對問題的理解,降低複雜度,而濫用繼承反而會增加系統構建和維護的難度以及系統的複雜度,因此需要慎重使用繼承複用。
本文來自部落格園,作者:碼農阿亮,轉載請註明原文連結:https://www.cnblogs.com/wml-it/p/17659171.html