装饰模式

装饰模式

1.何为装饰模式

​ 装饰模式动态地(组合)给一个对象增加一些额外的职责。就增加功能而言,它比继承更灵活。它能让我们在不修改原始类型也不产生大量派生类的情况下拓展功能(开闭原则)

2.装饰模式的意义和使用场景

​ 某些情况下我们可能会“过度使用继承来扩展对象的功能”,这缺乏灵活性,会导致子类急剧膨胀。装饰器模式将继承拓展改为组合拓展,在运行时动态地去拓展对象功能,符合了开闭原则,增加了灵活性。

3.装饰模式的实现

​ 创建一个装饰基类,装饰类继承于它。装饰类中有要装饰的对象的抽象基类(组合),以此来支持对同一基类不同子类对象的装饰。

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
// 基类流
class Stream {
public:
virtual void write(const std::string& data) = 0;
virtual std::string read() = 0;
};
// 具体流实现 - 网络流
class NetworkStream : public Stream {
public:
void write(const std::string& data) override {
}
std::string read() override {
}
};
// 具体流实现 - 文件流
class FileStream : public Stream {
public:
void write(const std::string& data) override {
}
std::string read() override {
}
};

// 具体流实现 - 内存流
class MemoryStream : public Stream {
public:
void write(const std::string& data) override {
}
std::string read() override {
}
};

// 装饰器基类
class StreamDecorator : public Stream { //这里继承是为了继承stream的接口
protected:
Stream* stream;
};

// 具体装饰器 - 加密
class EncryptionDecorator : public StreamDecorator {
public:
EncryptionDecorator(Stream* stream) : StreamDecorator(stream) {}

void write(const std::string& data) override {
// 在写入前对数据进行加密处理
stream->write(encryptedData);
}

std::string read() override {
// 在读取后对数据进行解密处理
return stream->read();
}
};

// 具体装饰器 - 缓存
class CachingDecorator : public StreamDecorator {
public:
CachingDecorator(Stream* stream) : StreamDecorator(stream) {}

void write(const std::string& data) override {
// 在写入前对数据进行缓存处理
stream->write(encryptedData);
}

std::string read() override {
// 在读取后对数据进行缓存处理
return stream->read();
}
};

int main() {
// 创建具体流对象
Stream* networkStream = new NetworkStream();
Stream* fileStream = new FileStream();
Stream* memoryStream = new MemoryStream();
// 使用装饰器进行加密和缓存
Stream* encryptedNetworkStream = new EncryptionDecorator(networkStream);
Stream* cachedFileStream = new CachingDecorator(fileStream);
// 写入和读取数据
encryptedNetworkStream->write("Data to encrypt and send over network");
cachedFileStream->write("Data to write in file and cache");

}