設計模式之七大原則

從今天起,以後每天學一點點設計模式的知識,同時把自己的學習記錄在csdn記錄下來,亦分享,亦查閱。 

                                                                                                                                                                             ——題記 


目錄

 1.開-閉原則

2.單一職責原則

3.里氏替換原則

4.依賴倒轉原則

5.合成/聚合複用原則

6.迪米特法則

7.接口隔離原則


 

面向對象的可複用設計的第一塊基石,便是所謂的“開-閉”原則

 1.開-閉原則(Open Closed Principle,OCP)

       “開-閉”原則講的是:一個軟件實體應當對擴展開放,對修改關閉。這個原則說的是,在設計一個模塊的時候,應當使這個模塊可以再不被修改的前提下被擴展。換言之,應當可以再不必修改源代碼的情況下改變這個模塊的行爲。

   所有的軟件系統都有一個共同的性質,即對它們的需求都會隨時間的推移而發生變化。在軟件系統面臨新的需求時,系統的設計必須是文檔的。滿足“開閉”原則的設計可以給一個軟件系統兩個無可比擬的優越性:

  • 通過擴展已有的軟件系統,可以提供新的行爲,以滿足對軟件的新需求,使變化中的軟件系統有一定的適應性和靈活性。

  • 已有的軟件模塊,特別是最重要的抽象層模塊不能再修改,這就使變化中的軟件系統有一定的穩定性和延續性。

   具有這兩個優點的軟件系統是一個在高層次上實現了複用的系統,也是一個易於維護的系統。

怎樣做到“開閉”原則

   咋看起來,不能修改而可以擴展似乎是自相矛盾的。怎麼可以同時又不修改、而又可以擴展呢?

抽象化是關鍵

   解決問題的關鍵在於抽象化。在像C++語言這樣的面向對象的編程語言裏面,可以給系統定義出一個一勞永逸、不再更改的抽象設計,此設計允許有無窮無盡的行爲在實現層被實現。在C++語言裏,可以給出一個或多個抽象C++類或C++接口,規定出所有的具體類必須提供的方法的特徵作爲系統設計的抽象層。這個抽象層預見了所有的可能擴展,因此在任何擴展情況下都不會改變。這就使得系統的抽象層不需修改,從而滿足了“開閉”原則的第二條:對修改關閉。

   同時,由於從抽象層導出了一個或多個新的具體類可以改變系統的行爲,因此係統的設計對擴展是開放的,這就滿足了“開閉”原則的第一條。

與其他設計原則的關係

   做到“開閉”原則不是一件容易的工作,但是也是有很多規律可循的。這些規律也同樣以設計原則的身份出現,但是它們都是“開閉”原則的手段和工具,是附屬於“開閉”原則的。

 

2.單一職責原則(Single Responsibility Principle, SRP)

 

單一職責原則 ,顧名思義,就是一個類只負責一個職責。它的定義也很簡單:這句話很好理解,就是說,不能有多個導致類變更的原因。

那這個原則有什麼用呢,它讓類的職責更單一。這樣的話,每個類只需要負責自己的那部分,類的複雜度就會降低。如果職責劃分得很清楚,那麼代碼維護起來也更加容易。試想如果所有的功能都放在了一個類中,那麼這個類就會變得非常臃腫,而且一旦出現bug,要在所有代碼中去尋找;更改某一個地方,可能要改變整個代碼的結構,想想都非常可怕。當然一般時候,沒有人會去這麼寫的。

 

當然,這個原則不僅僅適用於類,對於接口和方法也適用,即一個接口/方法,只負責一件事,這樣的話,接口就會變得簡單,方法中的代碼也會更少,易讀,便於維護。

 

事實上,由於一些其他的因素影響,類的單一職責在項目中是很難保證的。通常,接口和方法的單一職責更容易實現。

 

單一原則的好處:

代碼的粒度降低了,類的複雜度降低了。

可讀性提高了,每個類的職責都很明確,可讀性自然更好。

可維護性提高了,可讀性提高了,一旦出現 bug ,自然更容易找到他問題所在。

改動代碼所消耗的資源降低了,更改的風險也降低了。

3.里氏替換原則(Liskov Substitution Principle,LSP)

   里氏替換原則中說,任何基類可以出現的地方,子類一定可以出現。

   里氏替換原則是對“開閉”原則的補充。正如前面所提到的,實現“開閉”原則的關鍵步驟就是抽象化。而基類與子類的繼承關係就是抽象化的具體體現,所以里氏替換原則是對實現抽象化的具體步驟的規範。

   一般而言,違反里氏替換原則的,也違背“開閉”原則,反過來並不一定成立。

4.依賴倒轉原則(Dependency Inversion Principle,DIP)

   依賴倒轉原則講的是,要依賴於抽象,不要依賴於實現。

   看上去依賴倒轉原則與“開閉”原則有很大的相似之處,實際上,它們之間的關係是目標和手段之間的關係。“開閉”原則是目標,而達到這一目標的手段是依賴倒轉原則。

   換言之,要想實現“開閉”原則,就應當堅持依賴倒轉原則。違反依賴倒轉原則,就不可能達到“開閉”原則的要求。

5.合成/聚合複用原則(Composite/Aggregate Reuse Principle,CARP)

   要儘量使用合成/聚合,而不是繼承關係達到複用的目的。

   顯然,合成/聚合複用原則是與里氏替換原則相輔相成的,兩者又都是對實現“開閉”原則的具體步驟的規範。前者要求設計師首先考慮合成/聚合關係,後者要求在使用繼承關係時,必須確定這個關係時符合一定條件的。

6.迪米特法則(LOW OF DEMETER)

   一個軟件實體應當與儘可能少的其他實體發生相互作用。

   當一個系統面臨功能擴展的時候,其中會有一些模塊,它們需要修改的壓力比其他一些模塊要打。最後的結果可能是這些模塊需要修改或者不需要修改。但是不論是哪一種情況,如果這些模塊是相對孤立的,那麼它們就不會將修改的壓力傳遞給其他的模塊。

   這就是說,一個遵守迪米特法則設計出來的系統在功能需要擴展時,會相對更容易的做到對修改的關閉。也就是說,迪米特法則是一條通向“開閉”原則的道路。

7.接口隔離原則(Interface Segregation Principle,ISP)

   應當爲客戶端提供儘可能小的單獨的接口,而不要提供大的總接口。

   顯然,接口隔離原則與廣義的迪米特法則都是一個軟件實體與其他的軟件實體的通信的限制。廣義的迪米特法則要求儘可能限制通信的寬度和深度。接口隔離原則所限制的是通信的寬度,也就是,通信應當儘可能的窄。

   顯然,遵循接口隔離原則與迪米特法則會使一個軟件系統在功能擴展的過程當中不會講修改的壓力傳遞到其他的對象。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章