装饰者模式
Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的取代方案。
意图:
动态地给一个对象加入?一些额外的职责。就添加?功能来说,Decorator模式相比生成子类更为灵活。
设计原则:
1. 多用组合,少用继承。
利用继承设计子类的行为,是在编译时静态决定的,并且全部的子类都会继承到同样的行为。然而,假设可以利用组合的做法扩展对象的行为,就行在执行时动态地进行扩展。
2. 类应设计的对扩展开放,对改动关闭。
要点:
1. 装饰者和被装饰对象有同样的超类型。
2. 能够用一个或多个装饰者包装一个对象。
3. 装饰者能够在所托付被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。
4. 对象能够在不论什么时候被装饰,所以能够在执行时动态的,不限量的用你喜欢的装饰者来装饰对象。
5. 装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为。
6. 装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的详细类型。在实际项目中能够依据须要为装饰者加入?新的行为,做到“半透明”装饰者。
7. 适配器模式的用意是改变对象的接口而不一定改变对象的性能,而装饰模式的用意是保持接口并添加?对象的职责。
#include <iostream>
#include<cstdlib>
#include <algorithm>
#include<hash_map>
#include <vector>
#include <sstream>
#include<string>
using namespace std;
//enum condiment{DarkRost,Decat,Espresso,HouseBlend,Mocha,Soy,Whip};
class Beverage
{
public:
string description;
/*
hashmap<string,int> hash;
Beverage()
{
hash[condiment.Mocha]=0;
hash[condiment.Soy]=1;
hash[condiment.Whip]=2;
hash[condiment.DarkRost]=-1;
hash[condiment.Decat]=-1;
hash[condiment.Espresso]=-1;
hash[condiment.HouseBlend]=-1;
}*/
int size;//
int getSize()
{
return size;
}
void setSize(int Size)
{
size=Size;
}
virtual string getDescription()
{
return description;
}
virtual double cost()=0;
};
class Espresso :public Beverage
{
public :
Espresso()
{
description="Espresso";
}
double cost()
{
return 1.99;
}
};
class HouseBlend:public Beverage
{
public :
HouseBlend()
{
description="House Blend Coffee";
}
double cost()
{
return 0.89;
}
};
class DarkRost:public Beverage
{
public :
DarkRost()
{
description="DarkRost";
}
double cost()
{
return 0.99;
}
};
class Decat:public Beverage
{
public:
Decat()
{
description="Decat";
}
double cost()
{
return 1.05;
}
};
class CondimentDecorator:public Beverage
{
virtual string getDescription()=0;
};
class Mocha:public CondimentDecorator
{
Beverage *bEverage;
public:
Mocha(Beverage *beverage)
{
bEverage=beverage;
}
string getDescription()
{
return bEverage->getDescription()+",Mocha";
}
double cost()
{
return 0.20+bEverage->cost();
}
};
class Whip:public CondimentDecorator
{
Beverage *bEverage;
public:
Whip(Beverage *beverage)
{
bEverage=beverage;
}
string getDescription()
{
return bEverage->getDescription()+",Whip";
}
double cost()
{
return 0.10+bEverage->cost();
}
};
class Soy:public CondimentDecorator
{
Beverage *bEverage;
public:
Soy(Beverage *beverage)
{
bEverage=beverage;
}
string getDescription()
{
return bEverage->getDescription()+",Soy";
}
int getSize()
{
return bEverage->getSize();
}
double cost()
{
double cost=0.15+bEverage->cost();
if(getSize()==0)
{
cost+=0.10;
}
else if(getSize()==1)
{
cost+=0.15;
}
else
{
cost+=0.20;
}
return cost;
}
};
class Dictionary
{
public:
string change(string a)
{
vector<string> l;
stringstream ss(a);//stringstream由iostream派生而来提供读写string功能
//创建存储a副本 stringstream 对象其str string 类型对象
string s;
while (getline(ss, s, ‘,‘)) {
l.push_back(s);
}//getline 函数使用方法遇到,号时停止,并把ss中的字符串写到s中
sort(l.begin()+1,l.end());
string r;
for(vector<string>::iterator it=l.begin();it!=l.end();it++)
{
if(it!=l.begin())
{
r=r+‘,‘;
}
r+=*it;
}
return r;
}
};
int main()
{
Beverage *b=new Espresso();
Dictionary d;
cout<<b->getDescription()<<" $ "<<b->cost()<<endl;
Beverage *b1=new DarkRost();
b1=new Mocha(b1);
b1=new Mocha(b1);
b1=new Whip(b1);
cout<<d.change(b1->getDescription())<<" $ "<<b1->cost()<<endl;
Beverage *b2=new HouseBlend();
b2->setSize(2);
b2=new Soy(b2);
b2=new Mocha(b2);
b2=new Whip(b2);
cout<<d.change(b2->getDescription())<<" $ "<<b2->cost()<<endl;
//cout<<d.change("yells,hello,jil,sdj,sdk,zkl,wiei,woweo");
return 0;
}