装饰者模式
最后更新于:2022-04-01 20:29:18
## 模式定义:
装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
装饰者和被装饰者有相同的超累类型。
可以用一个或多个装饰者包装一个对象。
既然装饰者和被装饰者对象有相同的超累类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它。
装饰者可以委托被装饰者的行为之前与或之后,加上自己的行为,以达到特定的目的。
对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。
## 模式结构:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c5458d4c2a9.jpg)
## 举例:
购买咖啡时,可以在其中加入各种调料,例如:蒸奶(Steamed Milk),豆浆(Soy),摩卡(Mocha)或覆盖奶泡。咖啡馆会根据所加入的调料收取不同的费用。
解决方法:我们以饮料为主体,然后在运行时以调料来装饰饮料。比方说顾客想要摩卡和奶泡深焙咖啡,那么,要做的是:拿一个深焙咖啡(DarkRoast)对象,以摩卡(Mocha)对象装饰它,以奶泡对象装饰它,调用cost()方法,并依赖委托将调料的价钱加上去。
## UML设计:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-08-30_57c5458dcf1e5.jpg)
## 编程实现及执行结果:
~~~
#include
#include
using namespace std;
class Beverage
{
public:
Beverage(string str = "Unknow Beverage")
:description(str){}
virtual string getDescription()
{
return description;
}
virtual double cost(){return 0;}
private:
string description;
};
class CondimentDecorator : public Beverage
{
public:
string getDescription(){return "";}
};
class Espresso : public Beverage
{
public:
Espresso():Beverage("Espresso"){}
double cost()
{
return 1.99;
}
};
class HouseBlend : public Beverage
{
public:
HouseBlend():Beverage("HouseBlend Coffee"){}
double cost()
{
return 0.89;
}
};
class Mocha : public CondimentDecorator
{
public:
Mocha(Beverage* beve)
{
beverage = beve;
}
string getDescription()
{
return beverage->getDescription()+", Mocha";
}
double cost()
{
return 0.20 + beverage->cost();
}
private:
Beverage* beverage;
};
class Whip : public CondimentDecorator
{
public:
Whip(Beverage* beve)
{
beverage = beve;
}
string getDescription()
{
return beverage->getDescription()+", Whip";
}
double cost()
{
return 0.15 + beverage->cost();
}
private:
Beverage* beverage;
};
int main()
{
Beverage* pBeverage = new Espresso();
cout << pBeverage->getDescription() << " $" << pBeverage->cost() <getDescription() << " $" << pBeverage2->cost() <getDescription() << " $" << pBeverage2->cost() <
';