C Chapter3 裝飾模式

2021-05-22 10:15:40 字數 3868 閱讀 4129

單一職責原則:

單一職責原則,就乙個類而言,應該僅有乙個引起它變化的原因。如果乙個類承擔的職責過多,就等於把這些職責耦合在一起,乙個職責的變化可能會消弱或者抑制這個類完成其他職責的能力。這種耦合會導致脆弱的設計,當變化發生時,設計會遭受到意想不到的破壞。

軟體設計真正要做的許多內容,就是發現職責並把那些職責相互分離。如果你能夠想到多於乙個的動機去改變乙個類,那麼這個類就具有多於乙個的職責,就應該考慮類的職責分離。

開放-封閉原則:

是說軟體實體(類、模組、函式等等)應該可以擴充套件,但是不可修改。這個原則其實是有2個特徵,乙個是說「對於擴充套件是開放的(open for extension)」,另乙個是說「對於更改是封閉的(closed for modification)」。怎樣的設計才能面對需求的改變卻可以保持相對穩定,從而使得系統可以在第乙個版本以後不斷推出新的版本呢?

無論模組是多麼的「封閉」,都會存在一些無法對之封閉的變化。既然不可能完全封閉,設計人員必須對於他設計的模組應該對哪種變化封閉做出選擇。他必須先猜測出最有可能發生的變化種類,然後構造抽象來隔離那些變化。我們很難預先猜測,但是我們卻可以在發生小變化時,就及早去想辦法應對發生更大變化的可能。也就是說,等到變化發生時立即採取行動。

在我們最初編寫**時,假設變化不會發生時,我們就建立抽象來隔離以後發生的同類變化。面對需求,對程式的改動是通過增加新**進行的,而不是更改現有的**。這就是「開發-封閉原則」的精神所在。

當然並不是什麼時候應對變化都是容易的。我們希望的是在開發工作展開不久就知道可能發生的變化。查明可能發生的變化所等待的時間越長,要建立正確的抽象就越困難。

開放-封閉原則是物件導向設計的核心所在。遵循這個原則可以帶來物件導向技術所聲稱的巨大好處,也就是可維護性、可擴充套件性、可復用、靈活性好。開發人員應該僅對程式中呈現出頻繁變化的那些部分做出抽象,然而,對於應用程式中的每個部分都刻意地進行抽象同樣不是乙個好主意。拒絕不成熟的抽象和抽象本身一樣重要。

依賴倒轉原則

就是抽象不應該依賴細節,細節應該依賴於抽象。針對介面程式設計,不要對實現程式設計。比如:主機板、cpu、記憶體、硬碟都是針對介面設計的,如果針對實現來設計,記憶體就要對應到具體的某個品牌的主機板,那就會出現換記憶體需要把主機板也換了的尷尬。

a.高層模組不應該依賴低層模組。兩個都應該依賴抽象。

b.抽象不應該依賴細節。細節應該依賴抽象。

依賴倒轉其實可以說是物件導向設計的標誌,用哪些語言來編寫程式不重要,如果編寫時考慮的都是如何針對抽象程式設計而不是針對細節程式設計,即程式中所有的依賴關係都是終止於抽象類或者介面,那就是物件導向的設計,反之那就是過程化的設計了。

黎克特制代換原則

乙個軟體實體如果使用的是乙個父類的話,那麼一定適用於其子類,而且它察覺不出父類物件和子類物件的區別。也就是說,在軟體裡面,把父類都替換成它的子類,程式的行為沒有變化,簡單地說,子型別必須能夠替換掉它們的父型別。只有當子類可以替換掉父類,軟體單位的功能不受到影響時,父類才能真正被復用,而子類也能夠在父類的基礎上增加新的行為。由於子型別的可替換性才使得使用父類型別的模組在無需修改的情況下就可以擴充套件。

裝飾模式(decorator)

動態地給乙個物件新增一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。裝飾模式是為已有功能動態地新增更多功能的一種方式。

裝飾模式什麼時候用呢?

當系統需要新功能的時候,是向舊的類中新增新的**。這些新加的**通常裝飾了原有類的核心職責或主要行為。但這種做法的問題在於,他們在主類中加入了新的字段,新的方法和新的邏輯,從而增加了主類的複雜度。而這些新加入的東西僅僅是為了滿足一些只在某種特定情況下才會執行的特殊行為的需要。而裝飾模式卻提供了乙個非常好的解決方案,它把每個要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的物件,因此,當需要執行特殊行為時,客戶**就可以在執行時根據需要有選擇地、按順序地使用裝飾功能包裝物件了。

裝飾模式的優點:把類中的裝飾功能從類中搬移去除,這樣可以簡化原有的類。這樣做更大的好處就是有效地把類的核心職責和裝飾功能區分開了。而且可以去除相關類中複雜的裝飾邏輯。

工程結構:

(1)component.h 抽象類

(2)concretecomponent.h 具體待裝飾物件類

(3)decorator.h 抽象裝飾類

(4)concretedecoratora.h 具體裝飾類a

(5)concretedecoratorb.h 具體裝飾類b

(1)component.h 抽象類

(2)concretecomponent.h 具體待裝飾物件類

(3)decorator.h 抽象裝飾類

(4)concretedecoratora.h 具體裝飾類a

(5)concretedecoratorb.h 具體裝飾類b

//#include "stdafx.h"

#include "concretecomponent.h"

#include "concretedecoratora.h"

#include "concretedecoratorb.h"

int _tmain(int argc, _tchar* argv)

}int ipause = 0;

cin >> ipause;

return 0;}

裝飾模式是利用setcomponent來對物件進行包裝的。這樣每個裝飾物件的實現就和如何使用這個物件分離開了,每個裝飾物件只關心自己的功能,不需要關心如何被新增到物件鏈當中。

如果只有乙個concretecomponent類而沒有抽象的component類,那麼decorator類可以是concretecomponent的乙個子類。同樣道理,如果只有乙個concretedecorator類,那麼就沒有必要建立乙個單獨的decorator類,而可以把decorator和concretedecorator的責任合併成乙個類。

新版的裝飾模式

工程結構:

(1)person.h 待裝飾的人類

(2)decorator.h 裝飾類

(3)hats.h 具體裝飾類

(4)nikes.h 具體裝飾類

(5)trousers.h 具體裝飾類

(6)tshirts.h 具體裝飾類

(7)persondecorator.cpp 客戶端運用類

(1)person.h 待裝飾的人類

(2)decorator.h 裝飾類

(3)hats.h 具體裝飾類

(4)nikes.h 具體裝飾類

(5)trousers.h 具體裝飾類

(6)tshirts.h 具體裝飾類

(7)persondecorator.cpp 客戶端運用類

精通C Chapter3學習筆記

1 應用程式物件 定義main方法的類 2 static關鍵字 靜態成員是類級別的,而不是物件級別的,使用時不用先定義物件 3 main 方法是隱式私有的 private 4 慣例 返回值0表示程式正常結束 其他值表示非正常結束 void main 方法其實隱式返回0 5 system.enviro...

C Chapter19 命令模式

命令模式 command 將乙個請求封裝為乙個物件,從而使你可用不同的請求對客戶進行引數化 對請求排隊或記錄請求日誌,以及支援可撤銷的操作。命令模式的優點 第一,它能較容易地設計乙個命令佇列 第二,在需要的情況下,可以較容易地將命令記入日誌 第三,允許接收請求的一方決定是否要否決請求 第四,可以容易...

設計模式3 裝飾者模式

動態的將責任附加到物件上。想要擴充套件功能,裝飾者提供有別於繼承的另一種選擇 封裝變化 多用組合,少用繼承 針對介面程式設計,不針對實現程式設計 為互動物件之間的松耦合設計而努力 對擴充套件開放,對修改關閉 在購買咖啡時,可以要求在其中加入各種調料,例如 蒸奶,豆漿,摩卡等其他調料,會根據加入的不同...