C++設計模式


Ref: https://github.com/lichangqing2611/Cpp-Design-Patterns

什么是設計模式

“每一個模式描述了一個在我們周圍不斷重復發生的問題,以及該問題的解決方案的核心。這樣,你就能一次又一次地使用該方案而不必做重復勞動”。——Christopher Alexander

  • 好的面向對象設計是面對變化,提高軟件的復用性
  • 先尋找變化點,然后在變化點上應用設計模式,而不是任何時間任何地方都用。
  • 先寫代碼,而后采用設計模式進行重構。

如何解決復雜性?

  • 分解
    • 人們面對復雜性有一個常見的做法:即分而治之,將大問題分解為多個小問題,將復雜問題分解為多個簡單問題。
    • 分析問題的思路。
  • 抽象
    • 更高層次來講,人們處理復雜性有一個通用的技術,即抽象。由於不能掌握全部的復雜對象,我們選擇忽視它的非本質細節,而去處理泛化和理想化了的對象模型。
    • 編寫代碼的思路。

面向對象設計原則

1. 依賴倒置原則(DIP)

  • 高層模塊(穩定)不應該依賴於低層模塊(變化),二者都應該依賴於抽象(穩定) 。
  • 抽象(穩定)不應該依賴於實現細節(變化) ,實現細節應該依賴於抽象(穩定)。

    MainForm -> Line\Rect => MainFrom -> Shape <- Line\Rect

2. 開放封閉原則(OCP)

  • 對擴展開放,對更改封閉。
  • 類模塊應該是可擴展的,但是不可修改。

    對於改變應該盡量采用增加的方式對應,而不是修改的方式。

3. 單一職責原則(SRP)

  • 一個類應該僅有一個引起它變化的原因。
  • 變化的方向隱含着類的責任。

4. Liskov 替換原則(LSP)

  • 子類必須能夠替換它們的基類(IS-A)。
  • 繼承表達類型抽象。

5. 接口隔離原則(ISP)

  • 不應該強迫客戶程序依賴它們不用的方法。
  • 接口應該小而完備。

6. 優先使用對象組合,而不是類繼承

  • 類繼承通常為“白箱復用”,對象組合通常為“黑箱復用” 。

    小明的父類是人類,而不是小明的父親,通過理解的繼承關系有誤。

  • 繼承在某種程度上破壞了封裝性,子類父類耦合度高。
  • 而對象組合則只要求被組合的對象具有良好定義的接口,耦合度低。

7. 封裝變化點

  • 使用封裝來創建對象之間的分界層,讓設計者可以在分界層的一側進行修改,而不會對另一側產生不良的影響,從而實現層次間的松耦合。

8. 針對接口編程,而不是針對實現編程

  • 不將變量類型聲明為某個特定的具體類,而是聲明為某個接口。
  • 客戶程序無需獲知對象的具體類型,只需要知道對象所具有的接口。
  • 減少系統中各部分的依賴關系,從而實現“高內聚、松耦合”的類型設計方案。

重構技巧

  1. 靜態 -> 動態
  2. 早綁定 -> 晚綁定
  3. 繼承 -> 組合
  4. 編譯時依賴 -> 運行時依賴
  5. 緊耦合 -> 松耦合

從封裝變化角度對模式分類

組件協作:

單一職責:

對象創建:

對象性能:

接口隔離:

狀態變化:

數據結構:

行為變化:

領域問題:

現代較少用的模式

  • Builder
  • Mediator
  • Memento
  • Iterator
  • Chain of Resposibility
  • Command
  • Visitor
  • Interpreter

什么時候不用設計模式

  1. 代碼可讀性很差時
  2. 需要理解還很淺時
  3. 變化沒有顯現時
  4. 不是系統的關鍵依賴點
  5. 項目沒有復用價值時
  6. 項目將要發布時

Template Method

重點:

Observer/Event

重點:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM