设计模式的C++实现之装饰者模式2013-08-03 csdn LCL_data解决的问题:我们在装饰新家的时候买了几幅抽象画,买回来之后发现有些加上色彩艳丽的边框更适合我们,而有的加上玻璃罩之后更能符合我们的使用。那我们来怎么解决这个问题呢?他需要动态的给别的对象增加额外的职责,这就是装饰者模式的目的。我们可以通过继承的方式来给原对象增加新功能,但是装饰者模式采用组合的方式比生成子类更加灵活。类图及样例实现:

在装饰模式中的各个角色有:抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。具体装饰(Concrete Decorator)角色:负责给构件对象"贴上"附加的责任。
#include <string>#include <iostream>#include <memory>using namespace std;//抽象类Tankclass Tank{public:virtual void shot()=0;virtual void run()=0;public:virtual ~Tank(){cout<<"in the destructor of Tank"<<endl;} };//具体类 T50class T50:public Tank{public:void shot(){cout<<"Tank T50 shot()"<<endl;}void run(){cout<<"Tank T50 run()"<<endl;}public:virtual ~T50(){cout<<"In the destructor of T50"<<endl;}};//具体类T75class T75:public Tank{public:void shot(){cout<<"Tank T75 shot()"<<endl;}void run(){cout<<"Tank T75 run()"<<endl;}public:virtual ~T75(){cout<<"In the destructor of T75"<<endl;}};//抽象类,Decoratorclass Decorator:public Tank{protected:Tank* tank;public:Decorator(Tank* tank):tank(tank) {}//具体的坦克的装饰类virtual ~Decorator(){cout<<"In the destructor of Decorator"<<endl;}public:void shot(){tank->shot();}void run(){tank->run();}};class InfraredDecorator: public Decorator{private:string infrared;//这就是所谓的addAtrributepublic:InfraredDecorator(Tank* tank):Decorator(tank) {}virtual ~InfraredDecorator(){cout<<"in the destructor of InfraredDecorator"<<endl;}public:void set_Infrared(const string &infrared){this->infrared=infrared;}string get_infrared() const{return infrared;}void run(){tank->run();set_Infrared("+Infrared");cout<<get_infrared()<<endl;}void shot(){tank->shot();}};class AmphibianDecorator:public Decorator{private:string amphibian;public:AmphibianDecorator(Tank* tank):Decorator(tank) {}~AmphibianDecorator(){cout<<"in the destructor of AmphibianDecorator"<<endl;}public:void set_amphibian(const string &hibian){this->amphibian=hibian;}string get_amphibian() const{return amphibian;}public:void run(){tank->run();set_amphibian("+amphibian");cout<<get_amphibian()<<endl;}void shot(){tank->shot();}};int main(int argc, char **argv){//给T50增加红外功能Tank* tank1(new T50);Tank* pid1(new InfraredDecorator(tank1));pid1->shot();cout<<endl;pid1->run();cout<<endl;cout<<endl<<"---------------"<<endl;//给t75增加红外、两栖功能Tank* tank2(new T75);tank2->run();Tank* pid2(new InfraredDecorator(tank2));Tank* pad2(new AmphibianDecorator(pid2));pad2->shot();cout<<endl;pad2->run();cout<<endl;cout<<endl<<"--------------"<<endl;//动态撤销其他装饰 ?tank2->run();Tank * tank3(tank2);tank3->run();return 0;}