003 --- 第6章 装饰模式
简述:
装饰模式动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
装饰模式包括:抽象对象基类、具体对象类、抽象装饰类、具体装饰类。
抽象对象基类:定义一个对象接口,可以给这些对象动态的添加职责。
具体对象类:继承自抽象对象基类,定义了具体的对象,可以给这个对象添加一些职责。
抽象装饰类:继承自抽象对象基类,从类外扩展抽象对象基类的功能,但对于抽象对象基类来说,是无需知道抽象装饰类的存在的。
具体装饰类:就是具体的装饰对象类、起到给抽象对象基类添加职责的功能。
应用场景:为已有功能动态的添加更多功能,装饰类继承具体类的基类,将具体类的对象传入装饰类,装饰类内部执行具体类的逻辑和装饰类本身的逻辑
注:开发环境调整为VS2017,操作系统win11
装饰模式代码:
1 #include <iostream> 2 using namespace std; 3 4 // 装饰模式 5 // 抽象对象基类 6 class CComponent 7 { 8 public: 9 virtual void Operation() = 0; 10 }; 11 12 // 具体对象类 13 class CConcreteComponent : public CComponent 14 { 15 public: 16 virtual void Operation() 17 { 18 cout << "具体对象的操作" << endl; 19 } 20 }; 21 22 // 抽象装饰类 23 class CDecorator : public CComponent 24 { 25 protected: 26 CComponent* m_pComponent; 27 28 public: 29 CDecorator() : m_pComponent(NULL) {}; 30 31 void SetComponent(CComponent* pComponent) 32 { 33 m_pComponent = pComponent; 34 } 35 36 virtual void Operation() 37 { 38 if (m_pComponent != NULL) 39 { 40 m_pComponent->Operation(); 41 } 42 } 43 }; 44 45 // 具体装饰类 46 class CConcreteDecDecoratorA : public CDecorator 47 { 48 private: 49 string m_AddedState; 50 51 public: 52 virtual void Operation() 53 { 54 CDecorator::Operation(); 55 m_AddedState = "New State"; 56 cout << "具体装饰对象A的操作" << endl; 57 } 58 }; 59 60 // 具体装饰类 61 class CConcreteDecDecoratorB : public CDecorator 62 { 63 public: 64 virtual void Operation() 65 { 66 CDecorator::Operation(); 67 AddedBehavior(); 68 cout << "具体装饰对象B的操作" << endl; 69 } 70 71 private: 72 void AddedBehavior() 73 { 74 cout << "具体装饰对象B新增的行为" << endl; 75 } 76 }; 77 78 int main() 79 { 80 CConcreteComponent ConcreteComponent; 81 CConcreteDecDecoratorA ConcreteDecDecoratorA; 82 CConcreteDecDecoratorB ConcreteDecDecoratorB; 83 84 ConcreteDecDecoratorA.SetComponent(&ConcreteComponent); 85 ConcreteDecDecoratorB.SetComponent(&ConcreteDecDecoratorA); 86 ConcreteDecDecoratorB.Operation(); 87 88 system("pause"); 89 return 0; 90 }
输出结果:
例:GHL见妹子的打扮
代码如下:
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 // 人的类(具体对象类,本例不需要抽象对象基类) 6 class CPerson 7 { 8 private: 9 string m_szName; 10 11 public: 12 CPerson(){} 13 14 CPerson(string szName) 15 { 16 m_szName = szName; 17 } 18 19 virtual void Show() 20 { 21 string str = "装扮的[" + m_szName + "]"; 22 cout << str << endl; 23 } 24 }; 25 26 // 服装抽象类(抽象装饰类,继承自具体对象类) 27 class CFinery : public CPerson 28 { 29 protected: 30 CPerson* m_pComponent; 31 32 public: 33 void Decorate(CPerson* pComponent) 34 { 35 m_pComponent = pComponent; 36 } 37 virtual void Show() 38 { 39 if (m_pComponent) 40 m_pComponent->Show(); 41 } 42 }; 43 44 // 具体服饰类 45 // 大T恤类(具体装饰类,继承自抽象装饰类) 46 class CTShirts : public CFinery 47 { 48 public: 49 virtual void Show() 50 { 51 cout << "大T恤 "; 52 CFinery::Show(); 53 } 54 }; 55 56 // 垮裤类(具体装饰类,继承自抽象装饰类) 57 class CBigTrouser : public CFinery 58 { 59 public: 60 virtual void Show() 61 { 62 cout << "垮裤 "; 63 CFinery::Show(); 64 } 65 }; 66 67 // 破球鞋类(具体装饰类,继承自抽象装饰类) 68 class CSneakers : public CFinery 69 { 70 public: 71 virtual void Show() 72 { 73 cout << "破球鞋 "; 74 CFinery::Show(); 75 } 76 }; 77 78 // 西装类(具体装饰类,继承自抽象装饰类) 79 class CSuit : public CFinery 80 { 81 public: 82 virtual void Show() 83 { 84 cout << "西装 "; 85 CFinery::Show(); 86 } 87 }; 88 89 // 领带类(具体装饰类,继承自抽象装饰类) 90 class CTie : public CFinery 91 { 92 public: 93 virtual void Show() 94 { 95 cout << "领带 "; 96 CFinery::Show(); 97 } 98 }; 99 100 // 皮鞋类(具体装饰类,继承自抽象装饰类) 101 class CLeatherShoes : public CFinery 102 { 103 public: 104 virtual void Show() 105 { 106 cout << "皮鞋 "; 107 CFinery::Show(); 108 } 109 }; 110 111 int main() 112 { 113 CPerson Person("GHL"); 114 115 cout << "第一种装扮:" << endl; 116 CSneakers Sneakers; 117 CBigTrouser BigTrouser; 118 CTShirts TShirts; 119 Sneakers.Decorate(&Person); 120 BigTrouser.Decorate(&Sneakers); 121 TShirts.Decorate(&BigTrouser); 122 TShirts.Show(); 123 124 cout << "第二种装扮:" << endl; 125 CLeatherShoes LeatherShoes; 126 CTie Tie; 127 CSuit Suit; 128 LeatherShoes.Decorate(&Person); 129 Tie.Decorate(&LeatherShoes); 130 Suit.Decorate(&Tie); 131 Suit.Show(); 132 133 system("pause"); 134 return 0; 135 }
输出结果: