装饰者模式,给对象赋予新的职责(避免继承滥用)。
#include<iostream>
#include<sstream>
#include <string>
using namespace std;
class Beverage
{
protected:
string description ;
public:
virtual string getDescription()
{
return description;
}
virtual double cost() = 0;
};
class CondimentDecorator : public Beverage
{
public:
virtual string getDescription() = 0;
};
class HouseBlend : public Beverage
{
public:
HouseBlend()
{
description = "HouseBlend Coffee";
}
virtual double cost()
{
return 1.0;
}
};
class DarkRoast: public Beverage
{
public:
DarkRoast()
{
description = "DarkRoast Coffee";
}
virtual double cost()
{
return 2.0;
}
};
class Moca : public CondimentDecorator
{
Beverage* beverage;
public:
Moca(Beverage* bev)
{
this->beverage = bev;
}
virtual string getDescription()
{
return (beverage->getDescription() + " , Moca");
}
virtual double cost()
{
return beverage->cost() + 0.5;
}
};
class Soy : public CondimentDecorator
{
Beverage* beverage;
public:
Soy(Beverage* bev)
{
this->beverage = bev;
}
virtual string getDescription()
{
return (beverage->getDescription() + " , Soy");
}
virtual double cost()
{
return beverage->cost() + 1.0;
}
};
int main()
{
Beverage* b = new DarkRoast;
cout<<(b->getDescription())<<endl;
cout<<(b->cost())<<endl;
b = new Moca(b);
cout<<(b->getDescription())<<endl;
cout<<(b->cost())<<endl;
b = new Soy(b);
/*cout<<(b->getDescription())<<endl;
cout<<(b->cost())<<endl;*/
ostringstream sstr;
sstr << b->cost();
cout<<(b->getDescription()+ "\n"+ sstr.str())<<endl;
getchar();
return 0;
}
总结:
1. 注意父类的Beverage的cost函数是纯虚函数,因此它的子类必须遵守契约,每一个都必须实现cost。而在CondimentDecorator中,注意他是继承于Beverage, 目的是为了获取和Darkroast、HouseBlend一致的的类型,因为装饰者(moca coffee)必须要能替代被装饰者coffee。
2. 而在CondimentDecorator中,description是纯虚函数,继承它的子类必须遵守契约,每一个都必须实现description。在具体的装饰者内部(Moca和Soy)都维护了一个Beverage对象,这么做的目的是利用多态性获取相应的description和cost。