C++设计模式-装饰器(5)
设计模式:在解决某一类问题场景时,有既定的,优秀的代码框架可以直接使用,其优势如下:
- 代码更易于维护,代码的可读性,复用性,可移植性,健壮性会更好
- 当软件原有需求有变更或者增加新的需求时,合理的设计模式的应用,能够做到软件设计要求的
开-闭原则
,即对修改关闭,对扩展开放,使软件原有功能修改,新功能扩充非常灵活
- 合理的设计模式的选择,会使软件设计更加模块化,积极的做到软件设计遵循的根本原则
高内聚,低耦合
软件设计开-闭原则
:
开闭原则是软件设计中的一个重要原则,指的是软件实体(如类、模块、函数等)应该对扩展开放,对修改关闭。这意味着在不修改现有代码的基础上,通过扩展新功能来满足新的需求,从而提高软件的灵活性和可维护性
对扩展开放:允许在现有系统中添加新功能
对修改关闭:不需要修改现有的代码来添加新功能,避免引入新错误
通过遵循开闭原则,可以提高代码的可复用性和稳定性。常用的方法包括使用抽象类、接口以及多态等技术
结构型设计模式:
结构型设计模式关注类和对象的组合,旨在通过继承或接口来实现更大的结构(继承的概念被用来组合接口和定义组合对象获得新功能的方式)。这些模式帮助确保系统各部分之间的良好组织和交互。以下是一些常见的结构型设计模式
适配器模式(Adapter Pattern)
桥接模式(Bridge Pattern)
组合模式(Composite Pattern)
装饰器模式(Decorator Pattern)
外观模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
一、装饰器模式
装饰器模式(Decorator Pattern)是一种结构型设计模式,允许在不改变对象接口的情况下,动态地扩展对象的功能。这个模式通过创建一个装饰器类来包装原始对象,从而为其添加额外的职责
装饰器模式,与代理模式有相似的地方:装饰器类中有一个公共的抽象基类指针,指向需要增加功能的类;代理模式中,代理类中持有一个抽象公共基类指针指向所委托类的对象
主要角色:
组件(Component)– 抽象公共基类:定义了一个接口,可以对具体组件和装饰器进行操作
具体组件(Concrete Component):实现了组件接口,定义了一个基础功能的对象
装饰器(Decorator):持有一个组件对象的引用,并实现组件接口,定义了一个抽象装饰类
具体装饰器(Concrete Decorator):继承自装饰器,添加具体的功能或行为
1.示例代码1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
| class Car{ public: virtual void show() = 0; };
class Bmw:public Car{ void show() override { cout << "这是一辆宝马汽车,配置有: 基础配置"; } };
class Audi:public Car{ virtual void show() { cout << "这是一辆奥迪汽车,配置有: 基础配置"; } };
class Bnze:public Car{ void show() override { cout << "这是一辆奔驰汽车,配置有: 基础配置"; } };
class Decorator:public Car { public: Decorator(Car *p):pCar(p){} void show() override { if(pCar) { pCar->show(); } } private: Car *pCar; };
class CarDecorator1:public Decorator { public: CarDecorator1(Car *p): Decorator(p){} void show() override { Decorator::show(); addBehavior1(); }
private: void addBehavior1(){ cout << ",定速巡航"; } };
class CarDecorator2:public Decorator { public: CarDecorator2(Car *p): Decorator(p){} void show() override { Decorator::show(); addBehavior2(); }
private: void addBehavior2(){ cout << ",自动刹车"; } };
class CarDecorator3:public Decorator { public: CarDecorator3(Car *p): Decorator(p){} void show() override { Decorator::show(); addBehavior3(); }
private: void addBehavior3(){ cout << ",车道偏离"; } };
int main() { Car *p1 = new Bmw(); p1->show(); cout << endl;
p1 = new CarDecorator1(p1); p1->show(); cout << endl;
p1 = new CarDecorator2(p1); p1->show(); cout << endl;
p1 = new CarDecorator3(p1); p1->show(); cout << endl; }
|
编译运行:
1 2 3 4 5
| $ (base) zxz@ubuntu:~/Proj/C_C++/DesignPatterns/Decorators$ ./decorators 这是一辆宝马汽车,配置有: 基础配置 这是一辆宝马汽车,配置有: 基础配置,定速巡航 这是一辆宝马汽车,配置有: 基础配置,定速巡航,自动刹车 这是一辆宝马汽车,配置有: 基础配置,定速巡航,自动刹车,车道偏离
|
代码框图:

2.示例代码2
其实还可以对抽象装饰器进行省略,直接将具体装饰器从抽象组件进行派生,那么每一个具体组件中也需要显示的持有一个组件指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| class Car{ public: virtual void show() = 0; };
class Bmw:public Car{ void show() override { cout << "这是一辆宝马汽车,配置有: 基础配置"; } };
class Audi:public Car{ virtual void show() { cout << "这是一辆奥迪汽车,配置有: 基础配置"; } };
class Bnze:public Car{ void show() override { cout << "这是一辆奔驰汽车,配置有: 基础配置"; } };
class CarDecorator1:public Car { public: CarDecorator1(Car *p): pCar(p){} void show() override { pCar->show(); addBehavior1(); }
private: void addBehavior1(){ cout << ",定速巡航"; }
private: Car *pCar; };
class CarDecorator2:public Car { public: CarDecorator2(Car *p): pCar(p){} void show() override { pCar->show(); addBehavior2(); }
private: void addBehavior2(){ cout << ",自动刹车"; }
private: Car *pCar; };
class CarDecorator3:public Car { public: CarDecorator3(Car *p): pCar(p){} void show() override { pCar->show(); addBehavior3(); }
private: void addBehavior3(){ cout << ",车道偏离"; }
private: Car *pCar; };
int main() { Car *p1 = new Bmw(); p1->show(); cout << endl;
p1 = new CarDecorator1(p1); p1->show(); cout << endl;
p1 = new CarDecorator2(p1); p1->show(); cout << endl;
p1 = new CarDecorator3(p1); p1->show(); cout << endl; }
|
编译运行:
1 2 3 4 5
| (base) zxz@ubuntu:~/Proj/C_C++/DesignPatterns/Decorators$ ./decorators 这是一辆宝马汽车,配置有: 基础配置 这是一辆宝马汽车,配置有: 基础配置,定速巡航 这是一辆宝马汽车,配置有: 基础配置,定速巡航,自动刹车 这是一辆宝马汽车,配置有: 基础配置,定速巡航,自动刹车,车道偏离
|
代码框架:

装饰器模式通过在运行时动态地为对象添加功能,而无需改变对象的结构,提供了比继承更加灵活的解决方案。它是用于增强对象的功能或在不修改客户端代码的情况下对对象进行扩展的强大工具。适合那些需要在运行时添加功能、组合功能或需要灵活扩展功能的场景
3.装饰器模式的类型
基本装饰器(Basic Decorator):
- 用于在不改变类接口的情况下增加功能,通常为其他装饰器提供基础
具体装饰器(Concrete Decorators):
- 具体的装饰器实现了附加功能,如
CarDecorator1
和 CarDecorator2
4.优缺点
优点:
动态扩展功能:可以在运行时添加功能,而不需要修改对象的代码
遵循开闭原则:通过增加新装饰器类来扩展功能,而不修改现有代码
灵活性:可以通过不同的装饰器组合来实现各种功能的组合
缺点:
复杂性:装饰器的层次结构可能会变得复杂,增加理解和维护的难度
对象数量增加:使用装饰器会增加系统中的对象数量
适用场景:
需要动态地添加功能:在不改变原始对象的情况下添加功能
需要在不同的环境中组合功能:通过组合不同的装饰器来创建不同的功能
需要增加对象的职责:在对象的现有功能基础上添加额外的职责