裝飾者模式
時常會遇到這樣一種情況,我已經設計好了一個接口,並且也有幾個實現類,但是這時我發現我設計的時候疏忽了,忘記了一些功能,或者后來需求變動要求加入一些功能,最簡單的做法就是修改接口,添加函數,然后繼承類中都相應的添加實現,這樣做倒也沒什么問題,但是如果這種變化來個好幾次或者繼承類非常多,那工作量可就大了。
這時大神們就發明了裝飾者模式,在不修改現在有接口和實現類的基礎上實現功能或者狀態的添加。
從類圖上看,ConcreteComponent是Component原有的繼承類,而Decorator裝飾者類也繼承與Component,這樣的是讓Decorator的子類也可以方便的添加Component,而不用每個子類里面都去包含一次Component。(我的理解)
這樣客戶端使用的時候只需要知道ConcreteDecorator就可以直接調用Decorator的operation方法了,至於operation方法是怎么實現的以及使用的Component的哪一個子類是不需要關心的,而且添加的方法addBehavior也可以直接使用。
客戶端就無法依賴於抽象了,如果addBehavior的實現方法要變了,比較好的是添加新的ConcreteDecorator子類,或者繼承這個ConcreteDecorator重新實現addBehavior。
常用的情況
如果需要添加新功能,但又不想修改定義好的接口或者抽象類,那么這時候就比較適合裝飾模式,例如很多圖形系統中的組件,就可以使用裝飾模式,來讓新的組件在繼承現在功能的基礎上添加新的功能。
裝飾模式一般是針對接口或者抽象類的變化,如果是具體實現類的變化,則要考慮適用哪種模式。
優點
1.可以不用修改原有的接口,就可以實現新功能的添加。
2.裝飾者可以很方便的轉換原有接口中的實現,可以給裝飾者指定不同的ConcreteComponent實現不同的功能。
缺點
1.復雜性增加,裝飾者模式會導致許多小類的產生。
C++代碼實現
1 #ifndef _COMPONENT_H_ 2 #define _COMPONENT_H_ 3 4 5 class Component 6 { 7 public: 8 Component(); 9 virtual ~Component(); 10 11 virtual void operation() = 0; 12 }; 13 14 15 class ConcreteComponent: public Component 16 { 17 public: 18 ConcreteComponent(); 19 ~ConcreteComponent(); 20 21 void operation(); 22 }; 23 24 25 #endif
1 #include "Component.h" 2 #include <stdio.h> 3 4 5 6 Component::Component() 7 { 8 9 } 10 11 12 Component::~Component() 13 { 14 15 } 16 17 18 ConcreteComponent::ConcreteComponent() 19 { 20 21 } 22 23 24 25 ConcreteComponent::~ConcreteComponent() 26 { 27 28 } 29 30 31 void ConcreteComponent::operation() 32 { 33 fprintf(stderr, "ConcreteComponent's operation!\n"); 34 }

1 #ifndef _DECORATOR_H_ 2 #define _DECORATOR_H_ 3 4 #include "Component.h" 5 6 class Decorator: public Component 7 { 8 public: 9 Decorator(); 10 virtual ~Decorator(); 11 12 virtual void operation(); 13 virtual void setComponent(Component* pComponent); 14 15 protected: 16 Component* mComponent; 17 }; 18 19 20 class ConcreteDecorator: public Decorator 21 { 22 public: 23 ConcreteDecorator(); 24 virtual ~ConcreteDecorator(); 25 26 virtual void addBehavior(); 27 }; 28 29 30 #endif

1 #include "Decorator.h" 2 #include <stdio.h> 3 4 5 Decorator::Decorator() 6 { 7 8 } 9 10 11 Decorator::~Decorator() 12 { 13 14 } 15 16 17 void Decorator::operation() 18 { 19 mComponent->operation(); 20 } 21 22 23 void Decorator::setComponent(Component* pComponent) 24 { 25 this->mComponent = pComponent; 26 } 27 28 29 ConcreteDecorator::ConcreteDecorator() 30 { 31 32 } 33 34 35 ConcreteDecorator::~ConcreteDecorator() 36 { 37 38 } 39 40 41 42 void ConcreteDecorator::addBehavior() 43 { 44 fprintf(stderr, "ConcreteDecorator's addBehavior!\n"); 45 }

1 #include "Decorator.h" 2 3 4 5 int main() 6 { 7 Component* pComponent = new ConcreteComponent(); 8 ConcreteDecorator* pConDecorator = new ConcreteDecorator(); 9 pConDecorator->setComponent(pComponent); 10 pConDecorator->operation(); 11 pConDecorator->addBehavior(); 12 return 0; 13 }
1 g++ -o client client.cpp Component.cpp Decorator.cpp
運行結果