大話設計模式(C++)第六章-裝飾模式
二、概念
裝飾模式:動態地給一個物件新增一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。
裝飾模式是為已有功能動態地新增更多功能的一種方式。
三、說明
角色:
(1)Component是定義一個物件,可以給這些物件動態地新增職責。
(2)ConcreteComponent是定義了一個具體的物件,也可以給這個物件增加一些職責。
(3)Decorator,裝飾抽象類,繼承了Component,從外類來擴充套件Component類的功能,但是對於Component來說,是無需知道Decorator的存在的。
(4)至於ConcreteDecorator就是具體的裝飾物件,起到給Component新增職責的作用。
什麼時候用:
(1)需要在內部組裝完成再顯示出來的情況。
(2)類似於建造者模式,但是建造者模式的要求見到的過程必須是穩定的,而裝飾模式的建造過程是不穩定的。
(3)我們需要把所需的功能按正確的順序串聯起來進行控制。
在起初的設計中,當系統需要新功能的時候,是向舊的類中新增新的程式碼。這些新的程式碼通常裝飾了原有類的核心職責或主要行為,在主類中加入了新的欄位,新的方法和新的邏輯,從而增加了主類的複雜度,這些新加入的東西僅僅是為了滿足一些只在某種特定情況下才會執行的特殊行為的需要。
裝飾模式提供了一個非常好的解決方案,它把每個要裝飾的功能放在單獨的類中,並讓這個類包裝它所要修飾的物件,因此,當需要執行特殊行為時,客戶程式碼就可以在執行時根據需要有選擇地、按順序地使用裝飾功能包裝物件了。
優點:
(1)把類的裝飾功能從類中搬移去除,這樣可以簡化原有的類。
(2)有效地把類的核心職責和裝飾功能區分開來,而且可以去除相關類中重複的裝飾邏輯。
和建造者模式的區別?
建造者模式要求建造的過程必須是穩定的,而裝飾模式的建造過程是不穩定的,可以有各種各樣的組合方式。
#include <string> #include <iostream> //ConcreteComponent即Component class Person { private: std::string name; public: Person() {}; Person(std::string name) { this->name = name; } virtual void Show() { std::cout << "裝飾的" << name << std::endl; } }; //Decorator類(裝飾類),繼承了Persson類,並且弱擁有Person類 class Finery :public Person { protected: Person* component; //指標 public: void Decorator(Person* component) { this->component = component; //指標,指向同一地址 } void Show() { if (component != NULL) component->Show(); } }; //下面是一系列ConcreteDecorator類 class TShirts :public Finery { public: void Show() { std::cout << "大T恤 "; Finery::Show(); } }; //ConcreteDecorator類 class BigTrouser :public Finery { public: void Show() { std::cout << "垮褲 "; Finery::Show(); } }; //ConcreteDecorator類 class Sneakers :public Finery { public: void Show() { std::cout << "破球鞋 "; Finery::Show(); } }; //ConcreteDecorator類 class Suit :public Finery { public: void Show() { std::cout << "西裝 "; Finery::Show(); } }; //ConcreteDecorator類 class Tie :public Finery { public: void Show() { std::cout << "領帶 "; Finery::Show(); } }; //ConcreteDecorator類 class LeatherShoes :public Finery { public: void Show() { std::cout << "皮鞋 "; Finery::Show(); } }; int main() { Person* xc = NULL; xc = new Person("小菜"); std::cout << "第一種裝扮:" << std::endl; Sneakers* pqx = NULL; pqx = new Sneakers(); BigTrouser* kk = NULL; kk = new BigTrouser(); TShirts* dtx = NULL; dtx = new TShirts(); pqx->Decorator(xc); kk->Decorator(pqx); dtx->Decorator(kk); dtx->Show(); std::cout << "第二種裝扮:" << std::endl; LeatherShoes* px = NULL; px = new LeatherShoes(); Tie* ld = NULL; ld = new Tie(); Suit* xz = NULL; xz = new Suit(); px->Decorator(xc); ld->Decorator(px); xz->Decorator(ld); xz->Show(); if (xc != NULL) { delete xc; xc = NULL; } if (pqx != NULL) { delete pqx; pqx = NULL; } if (kk != NULL) { delete kk; kk = NULL; } if (dtx != NULL) { delete dtx; dtx = NULL; } if (px != NULL) { delete px; px = NULL; } if (ld != NULL) { delete ld; ld = NULL; } if (xz != NULL) { delete xz; xz = NULL; } return 0; }
原文參考: