feat: Decorator

Implemented a demo for the Decorator.
This commit is contained in:
Yuki 2025-04-12 03:01:38 +08:00
parent 1550d371d4
commit 9f29b7a6ff
Signed by: yuki
GPG Key ID: CF40579331C06C73
2 changed files with 56 additions and 0 deletions

51
10_decorator.cpp Normal file
View File

@ -0,0 +1,51 @@
#include <iostream>
#include <memory>
using namespace std;
class Coffee {
public:
virtual void make() = 0;
virtual ~Coffee() = default;
};
class SimpleCoffee : public Coffee {
public:
virtual void make() override {
cout << "Coffee";
}
};
class MilkDecorator : public Coffee {
unique_ptr<Coffee> coffee;
public:
MilkDecorator(unique_ptr<Coffee> c) : coffee(move(c)) {
}
virtual void make() override {
coffee->make();
cout << " + Milk";
}
};
class SugarDecorator: public Coffee {
unique_ptr<Coffee> coffee;
public:
SugarDecorator(unique_ptr<Coffee> c) : coffee(move(c)) {
}
virtual void make() override {
coffee->make();
cout << " + Sugar";
}
};
int main() {
auto coffee = make_unique<SimpleCoffee>();
auto milk_coffee = make_unique<MilkDecorator>(move(coffee));
auto sugar_coffee = make_unique<SugarDecorator>(move(milk_coffee));
sugar_coffee->make();
cout << endl;
}

View File

@ -66,3 +66,8 @@
组合模式正是为了解决这个问题。它的核心思想是:将对象组合成树形结构来表示“整体-部分”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。也就是说,我们可以将一个组件(由多个元素组成)当作一个普通元素一样来处理,统一操作接口,简化客户端代码。
## 装饰器模式Decorator
有时,我们需要给动态的一个类添加一些组件。例如:对于制作一杯咖啡,可以添加牛奶,糖等。一种做法是使用继承,这显然会造成类爆炸。另一种做法是将这些配料抽象成一个类,咖啡类维护一个配料的列表。对于纯数据,如计算最终价格,这样是合理的。但是对于添加额外行为,这就会将逻辑集中到 Coffee 类中。例如希望添加牛奶时咖啡必须加热,就不得不修改 Coffee 类,在它的 make 函数中添加处理逻辑。
装饰器模式解决了这个问题。让所有的配料都继承自 Coffee构建时则额外需要一个被装饰对象的指针构造函数中还能插入额外的处理。这样可以让每一层都能主动拦截、加工、改写行为而不需要集中到一个地方。对于客户端代码来说装饰器和原对象是一样的。当需要对咖啡做某个动作时可以对装饰器做装饰器再调用被修饰对象指针的对应动作。由于包含关系装饰器还天然记录了顺序。