C++装饰模式
意图
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator
模式相比生成子类更为灵活
适用性
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
- 处理那些可以撤销的职责
- 当不能采用生成子类的方法进行扩充时。一种情况时,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况是因为类定义被隐藏,或类定义不能用于生成子类。
模式结构
- 抽象构件角色:给出一个抽象接口,以规范准备接收附加责任的对象
- 具体构件角色:定义一个将要接收附加责任的类
- 装饰角色:持有一个构件对象的实例,并实现一个与抽象构件接口一致的接口
- 具体装饰角色:负责给构件对象添加上附加的责任
示意性代码
// 抽象构件角色:饮料
class Beverage {
public:
virtual ~Beverage() { }
virtual double cost() = 0;
};
// 具体构件角色:奶茶
class MilkTea : public Beverage {
public:
double cost() {
cout << "MilkTea cost: 5.5" << endl;
return 5.5;
}
};
// 具体构件角色:水果茶
class FruitTea : public Beverage {
public:
double cost() override {
cout << "FruitTea cost: 5.6" << endl;
return 5.6;
}
};
// 装饰角色:配料
class ToppingDecorator : public Beverage {
public:
ToppingDecorator(Beverage* beverage)
: m_beverage(beverage) { }
virtual ~ToppingDecorator() { delete m_beverage; }
virtual double cost() = 0;
protected:
Beverage* m_beverage;
};
// 具体装饰角色:pudding
class Pudding : public ToppingDecorator {
public:
Pudding(Beverage* beverage)
: ToppingDecorator(beverage) { }
double cost() override {
cout << "Adding pudding cost : " << COST << endl;
return COST + m_beverage->cost();
}
private:
int COST = 5;
};
// 具体装饰角色:Boba
class Boba : public ToppingDecorator {
public:
Boba(Beverage* beverage)
: ToppingDecorator(beverage) { }
double cost() override {
cout << "Adding boba cost: "
<< COST << endl;
return COST + m_beverage->cost();
}
private:
int COST = 2;
};
// 使用
int main() {
Beverage* myTea = new MilkTea();
myTea = new Boba(myTea); // 加一份Boba
myTea = new Boba(myTea); // 再加一份Boba
myTea = new Pudding(myTea); // 加一份Pudding
double totalCost = myTea->cost();
cout << totalCost << endl;
}