Decorator裝飾模式
作用:動態地給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。
UML圖如下:
Component是定義一個對象接口,可以給這些對象動態地添加職責。
ConcreteComponent是定義了一個具體的對象,也可以給這個對象添加一些職責。
Decorator,裝飾抽象類,繼承了Component,從外類來擴展Component類的功能,但對於Component來說,是無需知道Decorator的存在的。
至於ConcreteDecorator就是具體的裝飾對象,起到給Component添加職責的功能。
要善於變通,如果只有一個ConcreteComponent類而沒有抽象的Component類,那么Decorator類可以是ConcreteComponent的一個子類。
同樣道理,如果只有一個ConcreteDecorator類,那么就沒有必要建立一個單獨的Decorator類,而可以把Decorator和ConcreteDecorator的責任合並成一個類。
新加入的東西僅僅是為了滿足一些只在某種特定情況下才會執行的特殊行為 的需要。而裝飾模式卻提供了一個非常好的解決方案,它把每個要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的對象,因此,當需要執行特殊行為 時,客戶代碼就可以在運行時根據需要有選擇地、按順序地使用裝飾功能包裝對象了。
代碼如下:
Decorator.h
1 #ifndef _DECORATOR_H_ 2 #define _DECORATOR_H_ 3 4 //Component抽象類,定義該類對象的接口 5 class Component 6 { 7 public: 8 virtual ~Component(); 9 virtual void Operation()=0; 10 protected: 11 Component(); 12 }; 13 14 //ConcreteDecorator:具體的Component對象,可以給該對象動態 添加職責 15 class ConcreteComponent:public Component 16 { 17 public: 18 ConcreteComponent(); 19 ~ConcreteComponent(); 20 virtual void Operation(); 21 }; 22 23 //Decorator:裝飾抽象類,繼承自Component 24 class Decorator:public Component 25 { 26 public: 27 Decorator(Component* com); 28 void SetComponent(Component* com); 29 virtual ~Decorator(); 30 virtual void Operation(); 31 protected: 32 Component* _com; 33 }; 34 35 //ConcreteDecorator就是具體的裝飾對象之一,起到給Component添加職責的功能 36 class ConcreteDecoratorA:public Decorator 37 { 38 public: 39 ConcreteDecoratorA(Component* com); 40 ~ConcreteDecoratorA(); 41 virtual void Operation(); 42 void AddBehavorA(); 43 }; 44 45 //ConcreteDecorator就是具體的裝飾對象之二,起到給Component添加職責的功能 46 class ConcreteDecoratorB:public Decorator 47 { 48 public: 49 ConcreteDecoratorB(Component* com); 50 ~ConcreteDecoratorB(); 51 virtual void Operation(); 52 void AddBehavorB(); 53 }; 54 55 //ConcreteDecorator就是具體的裝飾對象之三,起到給Component添加職責的功能 56 class ConcreteDecoratorC:public Decorator 57 { 58 public: 59 ConcreteDecoratorC(Component* com); 60 ~ConcreteDecoratorC(); 61 virtual void Operation(); 62 void AddBehavorC(); 63 }; 64 65 //ConcreteDecorator就是具體的裝飾對象之四,起到給Component添加職責的功能 66 class ConcreteDecoratorD:public Decorator 67 { 68 public: 69 ConcreteDecoratorD(Component* com); 70 ~ConcreteDecoratorD(); 71 virtual void Operation(); 72 void AddBehavorD(); 73 }; 74 75 //只添加一種裝飾,則不用抽象出裝飾基類 76 class DecoratorOnlyOne:public Component 77 { 78 public: 79 DecoratorOnlyOne(Component* com); 80 ~DecoratorOnlyOne(); 81 virtual void Operation(); 82 void AddBehavor(); 83 private: 84 Component* _com; 85 }; 86 87 //如果只有一個ConcreteComponent類而沒有抽象的Component類,那么Decorator類可以是ConcreteComponent的一個子類。 88 //略 89 #endif
Decorator.cpp
1 #include "Decorator.h" 2 #include <iostream> 3 4 using namespace std; 5 6 Component::Component() 7 {} 8 9 Component::~Component() 10 { 11 cout << "~Component" << endl; 12 } 13 14 ConcreteComponent::ConcreteComponent() 15 {} 16 17 ConcreteComponent::~ConcreteComponent() 18 { 19 cout << "~ConcreteComponent" << endl; 20 } 21 22 void ConcreteComponent::Operation() 23 { 24 cout << "原職責:ConcreteComponent::Operation" << endl; 25 } 26 27 Decorator::Decorator(Component* com) 28 { 29 this->_com = com; 30 } 31 32 void Decorator::SetComponent(Component* com) 33 { 34 this->_com = com; 35 } 36 37 Decorator::~Decorator() 38 { 39 cout << "~Decorator" << endl; 40 delete this->_com; 41 this->_com = NULL; 42 } 43 44 void Decorator::Operation() 45 {} 46 47 ConcreteDecoratorA::ConcreteDecoratorA(Component* com):Decorator(com) 48 {} 49 50 ConcreteDecoratorA::~ConcreteDecoratorA() 51 { 52 cout << "~ConcreteDecoratorA" << endl; 53 } 54 55 void ConcreteDecoratorA::Operation() 56 { 57 this->_com->Operation(); 58 //附加職責A 59 this->AddBehavorA(); 60 } 61 62 void ConcreteDecoratorA::AddBehavorA() 63 { 64 cout << "附加職責A:ConcreteDecoratorA::AddBehavorA" << endl; 65 } 66 67 ConcreteDecoratorB::ConcreteDecoratorB(Component* com):Decorator(com) 68 {} 69 70 ConcreteDecoratorB::~ConcreteDecoratorB() 71 { 72 cout << "~ConcreteDecoratorB" << endl; 73 } 74 75 void ConcreteDecoratorB::Operation() 76 { 77 this->_com->Operation(); 78 //附加職責B 79 this->AddBehavorB(); 80 } 81 82 void ConcreteDecoratorB::AddBehavorB() 83 { 84 cout << "附加職責B:ConcreteDecoratorB::AddBehavorB" << endl; 85 } 86 87 ConcreteDecoratorC::ConcreteDecoratorC(Component* com):Decorator(com) 88 {} 89 90 ConcreteDecoratorC::~ConcreteDecoratorC() 91 { 92 cout << "~ConcreteDecoratorC" << endl; 93 } 94 95 void ConcreteDecoratorC::Operation() 96 { 97 this->_com->Operation(); 98 //附加職責C 99 this->AddBehavorC(); 100 } 101 102 void ConcreteDecoratorC::AddBehavorC() 103 { 104 cout << "附加職責C:ConcreteDecoratorC::AddBehavorC" << endl; 105 } 106 107 ConcreteDecoratorD::ConcreteDecoratorD(Component* com):Decorator(com) 108 {} 109 110 ConcreteDecoratorD::~ConcreteDecoratorD() 111 { 112 cout << "~ConcreteDecoratorD" << endl; 113 } 114 115 void ConcreteDecoratorD::Operation() 116 { 117 this->_com->Operation(); 118 //附加職責D 119 this->AddBehavorD(); 120 } 121 122 void ConcreteDecoratorD::AddBehavorD() 123 { 124 cout << "附加職責D:ConcreteDecoratorD::AddBehavorD" << endl; 125 } 126 127 //**************只添加一種修飾****************** 128 DecoratorOnlyOne::DecoratorOnlyOne(Component* com):_com(com) 129 { 130 } 131 132 DecoratorOnlyOne::~DecoratorOnlyOne() 133 { 134 cout << "~DecoratorOnlyOne" << endl; 135 delete this->_com; 136 this->_com = NULL; 137 } 138 139 void DecoratorOnlyOne::Operation() 140 { 141 this->_com->Operation(); 142 this->AddBehavor(); 143 } 144 145 void DecoratorOnlyOne::AddBehavor() 146 { 147 cout << "附加唯一職責:DecoratorOnlyOne::AddBehavor" << endl; 148 }
main.cpp
1 #include "Decorator.h" 2 #include <iostream> 3 4 using namespace std; 5 int main() 6 { 7 Component* pCom = new ConcreteComponent(); //要裝飾的對象 8 Decorator* pDec = NULL; 9 pDec = new ConcreteDecoratorA(pCom); //給裝飾對象附加職責A 10 pDec = new ConcreteDecoratorB(pDec); //給裝飾對象附加職責B 11 pDec = new ConcreteDecoratorC(pDec); //給裝飾對象附加職責C 12 pDec = new ConcreteDecoratorD(pDec); //給裝飾對象附加職責D 13 pDec->Operation(); 14 15 cout << "-------------------------------" << endl; 16 17 //只添加一種修飾 18 Component* pCom1 = new ConcreteComponent(); 19 DecoratorOnlyOne* pDec1 = new DecoratorOnlyOne(pCom1); 20 pDec1->Operation(); 21 22 cout << "-------------------------------" << endl; 23 24 delete pDec; 25 cout << "-------------------------------" << endl; 26 27 delete pDec1; 28 29 return 0; 30 }
運行結果:
Decorator模式除了采用組合的方式取得了比采用繼承方式更好的效果,Decorator模式還給設計帶來一種“即用即付”的方式來添加職責。在OO設計和分析經常有這樣一種情況:為了多態,通過父類指針指向其具體子類,但是這就帶來另外一個問題,當具體子類要添加新的職責,就必須向其父類添加一個這個職責的抽象接口,否則是通過父類指針是調用不到這個方法了。這樣處於高層的父類就承載了太多的特征(方法),並且繼承自這個父類的所有子類都不可避免繼承了父類的這些接口,但是可能這並不是這個具體子類所需要的。而在Decorator模式提供了一種較好的解決方法,當需要添加一個操作的時候就可以通過Decorator模式來解決,你可以一步步添加新的職責。