一、模式定义与核心思想
装饰模式(Decorator Pattern)是结构型设计模式的重要成员,核心思想是:通过组合而非继承的方式,动态为对象添加额外职责。它避免了继承体系的臃肿,允许灵活组合多个功能,实现 “即插即用” 的扩展效果。
关键特征:
装饰器与被装饰对象遵循同一接口(或继承同一基类)
装饰器持有被装饰对象的引用,实现功能叠加
支持多层装饰,形成职责链
二、UML 类图结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| +----------------+ | 抽象组件(Component) | +----------------+ | + operation() | +----------------+ ↑ | +----------------+ +----------------+ | 具体组件(Concrete) | | 装饰器基类(Decorator) | +----------------+ +----------------+ | + operation() | | - component | +----------------+ | + operation() | +----------------+ ↑ | +----------------+ | 具体装饰器(Concrete) | +----------------+ | + operation() | +----------------+
|
三、代码实现(文件读写场景)
1. 抽象组件:文件读写接口
1 2 3 4 5 6 7 8 9 10
| #include <string> // 抽象文件操作接口 class FileOperator { public: virtual ~FileOperator() = default; // 核心方法:读取文件内容 virtual std::string read() = 0; // 核心方法:写入文件内容 virtual void write(const std::string& content) = 0; };
|
2. 具体组件:基础文件操作类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <iostream> // 具体文件操作实现(无附加功能) class BasicFile : public FileOperator { private: std::string filename; public: BasicFile(const std::string& name) : filename(name) {} std::string read() override { std::cout << "[基础操作] 读取文件:" << filename << "\n"; return "原始文件内容"; // 模拟读取结果 } void write(const std::string& content) override { std::cout << "[基础操作] 写入文件:" << filename << ",内容:" << content << "\n"; } };
|
3. 装饰器基类
1 2 3 4 5 6 7 8 9 10 11 12
| // 装饰器基类(持有被装饰对象引用) class FileDecorator : public FileOperator { protected: FileOperator* component; // 被装饰的对象 public: FileDecorator(FileOperator* comp) : component(comp) {} ~FileDecorator() { delete component; } // 释放被装饰对象 // 委托给被装饰对象实现基础功能 std::string read() override { return component->read(); } void write(const std::string& content) override { component->write(content); } };
|
4. 具体装饰器:功能扩展
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
| #include <string> // 装饰器1:数据压缩功能 class CompressDecorator : public FileDecorator { public: CompressDecorator(FileOperator* comp) : FileDecorator(comp) {} std::string read() override { std::string content = FileDecorator::read(); std::cout << "[压缩装饰] 解压数据\n"; return content + "(已解压)"; // 模拟解压 } void write(const std::string& content) override { std::cout << "[压缩装饰] 压缩数据\n"; FileDecorator::write(content + "(已压缩)"); // 模拟压缩 } };
// 装饰器2:数据加密功能 class EncryptDecorator : public FileDecorator { public: EncryptDecorator(FileOperator* comp) : FileDecorator(comp) {} std::string read() override { std::string content = FileDecorator::read(); std::cout << "[加密装饰] 解密数据\n"; return content + "(已解密)"; // 模拟解密 } void write(const std::string& content) override { std::cout << "[加密装饰] 加密数据\n"; FileDecorator::write(content + "(已加密)"); // 模拟加密 } };
|
5. 调用示例:多层装饰组合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| int main() { // 1. 基础文件操作(无装饰) FileOperator* basic = new BasicFile("data.txt"); basic->read(); std::cout << "----------------\n"; // 2. 压缩+基础操作(单层装饰) FileOperator* compressFile = new CompressDecorator(new BasicFile("data.txt")); compressFile->write("测试内容"); std::cout << "----------------\n"; // 3. 加密+压缩+基础操作(多层装饰) FileOperator* encryptCompressFile = new EncryptDecorator(new CompressDecorator(new BasicFile("data.txt"))); encryptCompressFile->read(); // 释放资源(装饰器基类析构函数会递归释放) delete basic; delete compressFile; delete encryptCompressFile; return 0; }
|
四、与继承模式的对比
对比维度 |
装饰模式 |
继承模式 |
扩展方式 |
动态组合(运行时) |
静态继承(编译时) |
功能组合 |
支持多装饰器叠加(如加密 + 压缩) |
需创建多继承类(如 EncryptCompressFile) |
代码冗余 |
低(装饰器可复用) |
高(每新增组合需新增类) |
灵活性 |
支持动态添加 / 移除功能 |
功能固定,无法动态修改 |
五、应用场景与注意事项
适用场景
需动态扩展对象功能(如文件操作的压缩、加密、日志记录)
避免继承体系过度膨胀(如超过 3 层的继承关系)
需灵活组合多个功能(如同时添加缓存 + 权限校验)
注意事项
装饰器基类必须与被装饰对象实现同一接口
避免多层装饰导致的调试复杂度(建议不超过 3 层)
确保装饰器仅添加功能,不修改原有功能逻辑(遵循开闭原则)