装饰模式定义:装饰模式动态的将责任附加到对象上,若要扩展功能,装饰模式提供了比继承更有弹性的替代方案。
以大话设计模式中的例子来描述,
1,找出概念
装饰对象:人,(中国人,美国人等)
装饰器:鞋子、裤子、帽子、外套
2,既然要使用鞋子、裤子等装饰一个对象:人,则为穿了鞋子的人、穿了裤子的人、戴了帽子的人、穿了外套的人;其实都是在对人做装饰,且人原有的行为(接口函数)不能变;
为了让穿了鞋子的人和中国人保持统一的行为,需要定义一个抽象接口,让中国人和穿鞋子的人都继承这个接口;
我们定义这个接口为person,然后定义相关中国人,穿了鞋子的人等类,
另外穿了鞋子的人既然要装饰人就要拥有一个人成员来装饰,根据依赖倒置原则(高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象),所以在Shoe类中保存一个Persion指针(实际为Chinese类对象指针);
4,
目前的类图可以发现,所有装饰类中都有一个persion对象,根据重构中重复代码应该提取到父类原则,应该把persion_对象提取到父类Persion中,但那样的话类图很奇怪,类自己包含自己类型的一个成员对象(目前这种代码结构只在单例中存在);
5,
因此,我们需要提取一个父类来保存共有的成员对象persion_且要保持原有接口,Decorator类就诞生了,我们把persion_对象提取到Decorator类中,并且让Decoreator继承Persion类来保持原有的接口Show()的一致性;
(这里有一个比较有意思的现象:Decorator继承了Persion(保持接口的一致性),还保存了一个Persion指针类型的成员变量(是从各装饰子类提取的公共部分),这种代码结构目前只会在装饰模式中出现,以后如果看到代码里有这种结构,可以往装饰模式的角度阅读代码)
6,
现在的类图好看多了
完整代码如下:
1 #include <iostream> 2 #include <string> 3 4 class Persion { 5 public: 6 Persion() = default; 7 virtual ~Persion() {} 8 9 virtual void Show() = 0; 10 11 }; 12 13 class Chinese : public Persion { 14 public: 15 Chinese() = default; 16 ~Chinese() {} 17 18 virtual void Show() override { 19 std::cout << name_ << std::endl; 20 } 21 22 void SetName(const std::string& name) { 23 name_ = name; 24 } 25 26 private: 27 std::string name_; 28 }; 29 30 class Decorator : public Persion { 31 public: 32 Decorator() = default; 33 Decorator(Persion* persion) : persion_(persion) {} 34 ~Decorator() = default; 35 36 virtual void Show() override {} 37 38 protected: 39 Persion* persion_; 40 }; 41 42 class Shoe : public Decorator { 43 public: 44 Shoe(Persion* persion) : Decorator(persion) { 45 } 46 47 ~Shoe() = default; 48 49 virtual void Show() override { 50 persion_->Show(); // 此写法为正序 51 std::cout << "穿鞋子" << std::endl; 52 // persion_->Show(); // 此写法为倒序 53 } 54 }; 55 56 class Trousers : public Decorator { 57 public: 58 Trousers(Persion* persion) : Decorator(persion) { 59 } 60 61 ~Trousers() = default; 62 virtual void Show() override { 63 persion_->Show(); 64 std::cout << "穿裤子" << std::endl; 65 } 66 }; 67 68 class Hat : public Decorator { 69 public: 70 Hat(Persion* persion) : Decorator(persion) { 71 } 72 73 ~Hat() = default; 74 virtual void Show() override { 75 persion_->Show(); 76 std::cout << "戴帽子" << std::endl; 77 } 78 }; 79 80 class Coat : public Decorator { 81 public: 82 Coat(Persion* persion) : Decorator(persion) { 83 } 84 85 ~Coat() = default; 86 87 virtual void Show() override { 88 persion_->Show(); 89 std::cout << "穿外套" << std::endl; 90 } 91 }; 92 93 int main(int argc, char** argv) { 94 Chinese xm; 95 xm.SetName("小明"); 96 97 Trousers trous(&xm); 98 Shoe shoe(&trous); 99 Coat coat(&shoe); 100 Hat hat(&coat); 101 102 hat.Show(); 103 104 return 0; 105 }
运行结果:
原文:https://www.cnblogs.com/guoliushui/p/12222752.html