標籤:
裝飾模式(Decorator)就是動態地給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比產生子類更為靈活。
其結構圖如下:
Component是定義一個對象介面,可以給這些對象動態地添加責任。ConcreteComponent是定義了一個具體的對象,也可以給這個對象添加一些職責。Decorator裝飾抽象類別,繼承了Component,從外類來擴充Component類的功能,但對於Component來說,是無需知道Decorator的存在。ConcreteDecorator就是具體的裝飾對象,起到了給Component添加職責的功能。
下面是我用C語言代碼實現的,如果有誤請指出,以免誤人!!!
class Component{public: virtual void Operation() { printf("Component Operation\n"); }};class ConcreteCompoent :public Component{public: void Operation() { printf("ConcreteComponent Operation\n"); }};class Decorator :public Component{protected: Component* component;public: Decorator() { this->component = nullptr; } ~Decorator() { delete component; } void setComponent(Component* com) { if (component == nullptr) this->component = com; } void Operation() { component->Operation(); }};class ConcreteDecoratorA :public Decorator{private: string addedState;//本類的都有功能,以區別ConcreteDecoratorBpublic: void Operation() { Component::Operation(); addedState = "New State"; printf("具體裝飾對象A的操作\n"); }};class ConcreteDecoratorB :public Decorator{private: string addedState;//本類的都有功能,以區別ConcreteDecoratorBpublic: void Operation() { Component::Operation(); AddedBehavior(); } void AddedBehavior() { //本類都有的方法,以區別於ConcreteDecoratorA printf("具體裝飾對象B的操作\n"); }};//clientvoid main(void){ ConcreteCompoent* com = new ConcreteCompoent; ConcreteDecoratorA *comA = new ConcreteDecoratorA; ConcreteDecoratorB *comB = new ConcreteDecoratorB; comA->setComponent(com); comB->setComponent(comA); comB->Operation();
delete com;
delete comA;
delete comB;
}
裝飾模式是利用setComponent來對對象進行封裝的,這樣每個裝飾對象的實現就和如何使用這個對象分離開了,每個裝飾對象只關心自己的功能,不需要關心如何被添加到對象鏈當中。
如果只有一個ConcreteComponent類而沒有抽象的Componet類,那麼Decorator類可以是ConcreteComponent的一個子類。同樣道理,如果只有一個ConcreteDecorator類,那麼就沒有必要建立一個單獨的Decorator類,而可以把Decorator和ConcreteDecorator的責任合并成一個類。
以下是《大話設計模式》上面的“小菜穿衣約會MM”的例子用C++實現下:
class Person{private: string name;public: Person(){} Person(string name) { this->name = name; } virtual void show() { cout << name <<"的裝扮: "; }};class Finery :public Person{protected: Person *component;public: Finery(){} void Decorate(Person *com) { this->component = com; component->show(); } void show() { }};class TShirts :public Finery{public: void show() { cout << "T恤 "; }};class Trouser :public Finery{public: Trouser(){} void show() { cout << "跨庫 "; }};class Sneakers :public Finery{public: void show() { cout << "球鞋 "; }};class Suit :public Finery{public: void show() { cout << "西裝 "; }};class Tie :public Finery{public: void show() { cout << "領帶 "; }};class LeatherShoes :public Finery{public: void show() { cout << "皮鞋 "; }};//clientvoid main(void){ Person *p = new Person("小菜"); Sneakers *snekers = new Sneakers(); Trouser *trouser = new Trouser(); TShirts *shirt = new TShirts(); snekers->Decorate(p); trouser->Decorate(snekers); shirt->Decorate(trouser); shirt->show(); delete p; delete snekers; delete trouser; delete shirt;}
裝飾模式是為已有功能動態地添加更多功能的一種方式。當系統需要新功能的時候,是向舊的類中添加新的代碼,這些新加的代碼通常裝飾了原有類的核心職責或主要行為,在主類中加入了新的欄位,新的方法和新的邏輯,從而增加了主類的複雜度,而這些新加入的東西僅僅是為了滿足一些只在某種特定情況下才會執行的特殊行為的需要。而裝飾模式卻提供了一個非常好的解決方案,它把每個要裝飾的功能放在單獨的類中,並讓這個類封裝它要裝飾的對象,因此,當需要執行特殊行為時,用戶端代碼就可以在運行時根據需要有選擇地、按順序地使用裝飾功能封裝對象了。
裝飾模式的優點:把類中的裝飾功能從類中移除,可以簡化原有的類,有效地把類的核心職責和裝飾功能區分開來,而且可以去除相關類中重複的裝飾邏輯。
大話錦集(三)裝飾模式(Decorator)