解决的问题:当我们需要对一个对象添加新的功能。我们可以采用子类继承的方式来解决。
但是装饰者模式可以采用组合的方式,更加的灵活。比如我有一个人的抽象基类,从这个基类派生出了
中国人、美国人、新加坡人等具体类,他们有相同的方法:穿衣服()。我们想对这个穿衣服进行修饰,>比如穿什么衣服。我们再从人基类中派生出一个装饰类,表示这个装饰类专门用来装饰“人”的。
然后再具体的生成装饰,如从这个装饰类中派生出:牛仔裤()、T-shirt()、裙子()。这几个装饰可以任意组>合。
子类继承来扩展功能:每个子类都要单独写这个功能,代码不够灵活。
当在分析程序功能时,在需要经常要修改功能的地方可以利用这个方法。各功能部分作用
在装饰模式中的各个角色有:
抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的>接口。
具体装饰(Concrete Decorator)角色:负责给构件对象”贴上”附加的责任。
#include "stdafx.h"
#include<iostream>
#include<string>
using namespace std;
class human
{
public:
virtual void goHome()=0;
};
//被装饰的子类
class woman:public human
{
public:
void goHome()
{
cout<<"woman go home";
}
};
class man:public human
{
private:
string name;
public:
man(string name)
{
this->name=name;
}
string GetName()
{
return this->name;
}
void goHome()
{
cout<<"man go home";
}
};
//装饰类
class Deractor:public human
{
protected://子类继承后能继续访问,其他则不行
human *a;
public:
Deractor(human* person):a(person){};//本类中定义了一个基类的对象,用装饰类的构造函数完成初始。
void goHome()
{
a->goHome();
}
};
//特定的装饰类,主要操作是指针
class DeractorA_Car:public Deractor
{
private:
string tools;
public:
DeractorA_Car(human* person):Deractor(person){};
void SetCar(const string& str)
{
this->tools=str;
}
string GetCar()
{
return this->tools;
}
void goHome()//装饰后新的goHome()
{
a->goHome();//调用父类的goHome功能
SetCar("+Car");//添加功能
cout<<GetCar();
}
};
class DeractorB_train:public Deractor
{
private:
string tools;//附加的功能
public:
DeractorB_train(human* person):Deractor(person){};
void Settrain(const string& str)
{
this->tools=str;
}
string Gettrain()
{
return this->tools;
}
void goHome()
{
a->goHome();
Settrain("+train");
cout<<Gettrain();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
human *a(new man("KK"));//定义一个人指针,指向一个男人。
human *b(new DeractorA_Car(a));//对a指向的男人复制一个,且增加新的功能:有车
human *c(new DeractorB_train(b));
c->goHome();//配上地铁和车后
//动态功能撤销
cout<<endl;
b->goHome();//撤销通过“坐火车”回家的附加装饰功能
cout<<endl;
a->goHome();//撤销“做汽车”、“坐火车” 功能
return 0;
}