1. 課程簡介
本周開始進入到《C++設(shè)計模式》課程中。
A. 課程目標
a. 理解松耦合設(shè)計思想
b. 掌握面向?qū)ο笤O(shè)計原則
c. 掌握重構(gòu)技法改善設(shè)計
d. 掌握GOF核心設(shè)計模式
B. 什么是設(shè)計模式
設(shè)計模式描述了一個重復發(fā)生的問題及該問題解決方案的核心。其目的在于提高軟件設(shè)計過程中代碼的復用率,提高代碼抵抗變化的能力。
本課程以面向?qū)ο鬄榛A(chǔ),主要學習掌握“好的面向?qū)ο笤O(shè)計”。
2. 面向?qū)ο笤O(shè)計原則
面向?qū)ο笤O(shè)計原則在很多時候比具體的設(shè)計模式更為重要,設(shè)計模式是這些設(shè)計原則的實現(xiàn)。
A. 依賴倒置原則(DIP)
- 高層模塊(穩(wěn)定)不應該依賴于低層模塊(變化),二者都應該依賴于抽象(穩(wěn)定)。
- 抽象(穩(wěn)定)不應該依賴于實現(xiàn)細節(jié)(變化),實現(xiàn)細節(jié)應該依賴于抽象(穩(wěn)定)。
B. 開放封閉原則(OCP)
- 對擴展開放,對更改封閉。
- 類模塊應該是可擴展的,但是不可修改。
C. 單一職責原則(SRP)
- 一個類應該僅有一個引起它變化的原因。
- 變化的方向隱含著類的責任。
D. Liskov 替換原則(LSP)
- 子類必須能夠替換它們的基類(is-a)。
- 繼承表達類型抽象
E. 接口隔離原則(ISP)
- 不應該強迫客戶程序依賴它們不用的方法。
- 接口應小而完備。
F. 優(yōu)先使用對象組合,而不是類繼承
- 類繼承通常為“白箱復用”,對象組合通常為“黑箱復用”。
- 繼承在某種程度上破壞了封裝性,子類父類耦合度高。
- 而對象組合則只要求被組合的對象具有良好定義的接口,耦合度低。
G. 封裝變化點
- 使用封裝來創(chuàng)建對象之間的分界層,讓設(shè)計者可以在分界層一側(cè)進行修改,而不會對另一側(cè)產(chǎn)生不良的影響,從而實現(xiàn)層次間的松耦合。
H. 針對接口編程,而不是針對實現(xiàn)編程
- 不將變量類型聲明為某個特定的具體類,而是聲明為某個接口。
- 客戶程序無需獲知對象的具體類型,只需要知道對象所具有的接口。
- 減少系統(tǒng)中各部分的依賴關(guān)系,從而實現(xiàn)“高內(nèi)聚,松耦合”的類型設(shè)計方案。
3. 從封裝變化角度對模式分類
A. 組件協(xié)作
- Template Method
- Strategy
- Observer / Event
B. 單一職責
- Decorator
- Bridge
C. 對象創(chuàng)建
- Factory Method
- Abstract Factory
- Prototype
- Builder
D. 對象性能
- Singleton
- Flyweight
E. 接口隔離
- Facade
- Proxy
- Mediator
- Adapter
F. 狀態(tài)變化
- Memento
- State
G. 數(shù)據(jù)結(jié)構(gòu)
- Composite
- Iterator
- Chain of Resposibility
H. 行為變化
- Command
- Visitor
I. 領(lǐng)域問題
- Interpreter
4. 重構(gòu)關(guān)鍵技法
- 靜態(tài)
->動態(tài) - 早綁定
->晚綁定 - 繼承
->組合 - 編譯時依賴
->運行時依賴 - 緊耦合
->松耦合
5. “組件協(xié)作”模式
現(xiàn)代軟件專業(yè)分工之后的第一個結(jié)果是“框架與應用程序的劃分”,“組件協(xié)作”模式通過晚期綁定,來實現(xiàn)框架與應用程序之間的松耦合,是二者之間協(xié)作時常用的模式。
A. 模板方法(Template Method)
-
動機
在軟件構(gòu)建過程中,對于某一項任務(wù),它常常有穩(wěn)定的整體操作結(jié)構(gòu),但各個子步驟卻有很多改變的需求,或者由于固有的原因(比如框架與應用之間的關(guān)系)而無法和任務(wù)的整體結(jié)構(gòu)同時實現(xiàn)。
如何在確定穩(wěn)定操作結(jié)構(gòu)的前提下,來靈活應對各個子步驟的變化或者晚期實現(xiàn)需求?
優(yōu)化前流程優(yōu)化后流程模式定義結(jié)構(gòu)要點總結(jié)
B. 策略模式(Strategy)
-
動機
在軟件構(gòu)建過程中,某些對象使用的算法可能多種多樣,經(jīng)常改變,如果將這些算法都編碼到對象中,將會使對象變得異常復雜;而且有時候支持不使用的算法也是一個性能負擔。
如何在在運行時根據(jù)需要透明地理性對象的算法?將算法與對象本身解耦,從而避免上述問題?
模式定義結(jié)構(gòu)要點總結(jié)
C. 觀察者模式(Observer)
-
動機
在軟件構(gòu)建過程中,我們需要為某些對象建立一種“通知依賴關(guān)系”——一個對象(目標對象)的狀態(tài)發(fā)生改變,所有的依賴對象(觀察者對象)都將得到通知。如果這樣的依賴關(guān)系過于緊密,將使軟件不能很好地抵御變化。
使用變身對象技術(shù),可以將這種依賴關(guān)系弱化,并形成一種穩(wěn)定的依賴關(guān)系。從而實現(xiàn)軟件體系結(jié)構(gòu)的松耦合。
模式定義結(jié)構(gòu)要點總結(jié)
6. “單一職責”模式
在軟件組件的設(shè)計中,如果責任劃分不清晰,使用繼承得到的結(jié)果往往是隨著需求的變化,子類急劇膨脹,同時充斥著重復代碼,這時候的關(guān)鍵是劃清責任。
A. 裝飾模式(Decorator)
-
動機
在某些情況下我們可能會“過度地使用繼承來擴展對象的功能”,由于繼承為類型引入的靜態(tài)特質(zhì),使得這種擴展方式缺乏靈活性;并且隨著子類的增多(擴展功能的增多),各種子類的組合(擴展功能的組合)會導致更多子類的膨脹。
如何使“對象功能的擴展”能夠根據(jù)需要來動態(tài)地實現(xiàn)?同時避免“擴展功能的增多”帶來的子類膨脹問題?從而使得任何“功能擴展變化”所導致的影響降為最低?
模式定義結(jié)構(gòu)要點總結(jié)
B. 橋模式(Bridge)
-
動機
由于某些類型的固有的實現(xiàn)邏輯,使得它們具有兩個變化的維度,乃至多個維度的變化。
如何應對這種“多維度的變化”?如何利用面向?qū)ο蠹夹g(shù)來使得類型可以輕松地沿著兩個乃至多個方向變化,而不引入額外的復雜度?
模式定義結(jié)構(gòu)要點總結(jié)
















