一、模式定义与核心思想

装饰模式(Decorator Pattern)是结构型设计模式的重要成员,核心思想是:通过组合而非继承的方式,动态为对象添加额外职责。它避免了继承体系的臃肿,允许灵活组合多个功能,实现 “即插即用” 的扩展效果。

关键特征:

  1. 装饰器与被装饰对象遵循同一接口(或继承同一基类)

  2. 装饰器持有被装饰对象的引用,实现功能叠加

  3. 支持多层装饰,形成职责链

二、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 层)

确保装饰器仅添加功能,不修改原有功能逻辑(遵循开闭原则)