装饰器模式的核心思想是通过组合替代继承,在不修改原有类代码的基础上,动态给对象添加额外职责。C++中借助虚函数实现多态特性,配合包装类的设计,可以很好地落地这种模式,实现类功能的动态增强。

装饰器模式核心设计思路
整个设计分为四个核心部分:抽象组件类、具体组件类、抽象装饰器类、具体装饰器类。抽象组件类定义统一的功能接口,具体组件类实现基础功能,抽象装饰器类继承抽象组件类并持有抽象组件对象的指针,具体装饰器类则在调用原有功能的基础上添加新的增强逻辑。
1. 抽象组件类定义
首先定义一个抽象基类,作为所有组件和装饰器的统一接口,内部声明纯虚函数作为功能入口:
// 抽象组件类,定义统一的功能接口
class Component {
public:
virtual ~Component() = default;
// 纯虚函数,定义核心功能
virtual void operation() = 0;
};
2. 具体组件类实现
具体组件类继承抽象组件类,实现基础的核心功能,后续的功能增强都围绕这个类展开:
// 具体组件类,实现基础功能
class ConcreteComponent : public Component {
public:
void operation() override {
// 基础功能逻辑
printf("执行基础组件的核心功能n");
}
};
3. 抽象装饰器类设计
抽象装饰器类同样继承抽象组件类,内部持有一个抽象组件对象的指针,用于关联被装饰的对象:
// 抽象装饰器类,继承组件接口并持有组件对象
class Decorator : public Component {
protected:
// 持有被装饰的组件对象指针
Component* component;
public:
// 构造函数传入需要装饰的组件对象
explicit Decorator(Component* comp) : component(comp) {}
virtual ~Decorator() {
delete component;
component = nullptr;
}
// 默认调用被装饰对象的原有功能
void operation() override {
if (component != nullptr) {
component->operation();
}
}
};
4. 具体装饰器类实现
具体装饰器类继承抽象装饰器类,重写operation方法,在调用原有功能的前后添加新的增强逻辑:
// 具体装饰器A,添加功能增强A
class ConcreteDecoratorA : public Decorator {
public:
explicit ConcreteDecoratorA(Component* comp) : Decorator(comp) {}
void operation() override {
// 增强逻辑:调用原有功能前执行额外操作
printf("装饰器A:执行功能增强前置逻辑n");
// 调用被装饰对象的原有功能
Decorator::operation();
// 增强逻辑:调用原有功能后执行额外操作
printf("装饰器A:执行功能增强后置逻辑n");
}
};
// 具体装饰器B,添加功能增强B
class ConcreteDecoratorB : public Decorator {
public:
explicit ConcreteDecoratorB(Component* comp) : Decorator(comp) {}
void operation() override {
printf("装饰器B:执行功能增强前置逻辑n");
Decorator::operation();
printf("装饰器B:执行功能增强后置逻辑n");
}
};
完整使用示例
通过组合不同的装饰器,可以动态为对象添加不同的功能增强,不需要修改原有组件类的代码:
#include <cstdio>
// 上述所有类的定义放在这里
int main() {
// 创建基础组件对象
Component* component = new ConcreteComponent();
printf("=== 仅执行基础功能 ===n");
component->operation();
// 用装饰器A包装基础组件,添加增强A
Component* decoratedA = new ConcreteDecoratorA(component);
printf("n=== 基础功能+装饰器A增强 ===n");
decoratedA->operation();
// 在装饰器A的基础上再用装饰器B包装,添加增强B
Component* decoratedAB = new ConcreteDecoratorB(decoratedA);
printf("n=== 基础功能+装饰器A+装饰器B增强 ===n");
decoratedAB->operation();
// 释放内存,装饰器析构时会自动释放内部的组件对象
delete decoratedAB;
return 0;
}
设计优势总结
这种包装类与虚函数组合的设计,相比直接通过继承扩展功能,有以下几个明显优势:
- 符合开闭原则,新增功能增强时不需要修改原有组件类的代码,只需要新增具体装饰器类即可
- 功能增强可以动态组合,通过不同的装饰器嵌套顺序,可以得到不同的功能组合效果,比静态继承更灵活
- 避免了继承带来的类爆炸问题,如果有N种基础功能和M种增强功能,继承方式需要N*M个子类,而装饰器模式只需要N+M个类
需要注意的是,装饰器模式会增加对象的数量,同时装饰器的嵌套层级过深时,调试功能调用链路会变得稍微复杂,实际使用中需要根据场景合理控制装饰器的嵌套深度。