目录
1. 模式的演进
1.1 星巴兹咖啡
咖啡店有多种咖啡,有多种调料
根据咖啡不同,调料不同进行价格计算
调料可能需要双份,三份
1.2 第一次错误尝试-类爆炸
把每种组合都设计成一种类
缺点:在维护时,如果价格有变化将会是噩梦
1.3 第二次尝试-不易扩展
通过设置是否有调料进行价格的计算
缺点:如果要双份调料呢,如果调料价格调整呢(全部涉及的代码全部都要改),如果加入新型调料呢
1.4 装饰者模式
装饰者模式其实利用装饰者和被装饰者都是继承相同的超类,被装饰者被装饰者装饰后还可以被装饰,实现了装饰的自由。
被装饰者被装饰后,其实是将被装饰者的对象放在了装饰者中,外表其实是装饰者
其实这和咖啡也挺像的,咖啡是饮料,加入调料还是饮料
1.装饰者和被装饰者对象有相同的超类型
2.你可以用一个或多个装饰者包装一个对象
3.既然装饰者和被装饰者对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它
4.装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的
5.对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢地装饰者来装饰对象
2.总类图和部分源码
2.1 总类图
2.2 部分源码
2.2.1 Beverage.h
enum Size{TALL, GRANDE, VENTI };
class Beverage{
public:
Beverage();
virtual string getDescription();
virtual double cost()=0;
virtual ~Beverage();
string description="Unknow Beverage";
void setSize(Size size);
Size getSize();
private:
Size size=TALL;
};
2.2.2 CondimentDecorator.h
#include "Beverage.h"
class CondimentDecorator:public Beverage{
public:
CondimentDecorator();
virtual string getDescription()=0;
virtual ~CondimentDecorator();
Beverage *beverage;
Size getSize();
};
2.2.3 HouseBlend.h
#include "Beverage.h"
class HouseBlend:public Beverage{
public:
HouseBlend();
virtual double cost()override final;
virtual ~HouseBlend();
};
2.2.4 Milk.h
#include "CondimentDecorator.h"
class Milk:public CondimentDecorator{
public:
Milk(Beverage *beverage);
virtual string getDescription()override final;
virtual double cost()override final;
virtual ~Milk();
};
2.2.5 关于cost() 和 getDescription()实现-委托、递归
装饰者拥有被装饰者对象,所以当要进行价格计算时,通过自己地价格与被装饰者价格的相加得出总价。同样,也可以通过此方法进行说明的打印
这递归调用cost从外面一层一层调用里面的cost直到到达最里面,再一层一层返回结果
string Milk::getDescription()
{
return beverage->getDescription() + ", Milk";
}
double Milk::cost()
{
return 0.10+beverage->cost();
}
3.总结
1.装饰者模式:动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承地另一种选择
2.设计原则:对扩展开放,对修改关闭
3.要点: