俗套点,先来个装饰者模式的定义吧--装饰者模式可以动态地给一个对象增加其他职责。就扩展对象功能来说,装饰者模式比生成子类更为灵活。
下面谈谈我对装饰者模式的一些理解吧:首先,装饰者的基类与被装饰者都派生于一个共同的基类CComponent,有着公共的接口Operation,被装饰者实现了其的基本行为,而装饰者的基类派生于CComponent类,更重要的是其内部有一个维护记录装饰者的CComponent指针,指向被装饰的对象,该对象可以是没有装饰过的对象,也可以是装饰过的对象。该基类实现的行为则是调用该CComponent指针实际指向的的装饰者对象的行为。而由此装饰类派生出的具体装饰类中的行为定义中除了自己附加行为的实现,还要调用装饰者基类的装饰行为。
这样,有以下优点:1.装饰者模式提供了统一的接口来管理,都可以运用CComponent指针来进行管理。2.可以动态的组合装饰行为来装饰被装饰者。尽可能的减少新的对象的产生是考重新继承派生来实现,而是通过组合的方式来实现。
下面找了一个比较容易理解的类图(类图是转载的哦)
下面是一个例子代码,理解不正确和代码有误的地方希望大家多多指正哦
有个问题就是:m_people这个变量是个私有变量,为什么在公共继承的子类中其应该是不可访问的,而以下代码运行起来确没有问题内?茫然
class CComponent
{
public:
virtual void Operation() = 0;
};
//被装饰者类
class CPeople:public CComponent
{
public:
virtual void Operation();
};
void CPeople::Operation()
{
cout<<"I am a peopele!"<<endl;
}
//装饰者类的基类
class Decrotor:public CComponent
{
public:
Decrotor(CComponent* cpn):m_people(cpn){};
virtual void Operation();
private:
//被装饰的对象指针
CComponent* m_people;
};
void Decrotor::Operation()
{
if (m_people != NULL)
{
m_people->Operation();
}
}
//帽子装饰类
class CHatDecrotor : public Decrotor
{
public:
CHatDecrotor(CComponent* cpn):Decrotor(cpn){};
virtual void Operation();
};
void CHatDecrotor::Operation()
{
cout<<"I haved weared a hat"<<endl;
Decrotor::Operation();
}
//鞋子装饰类
class CShoeDecrotor : public Decrotor
{
public:
CShoeDecrotor(CComponent* csn):Decrotor(csn){};
virtual void Operation();
};
void CShoeDecrotor::Operation()
{
Decrotor::Operation();
cout<<"I have weared a pair of shoes"<<endl;
}
//衣服装饰类
class CClothes:public Decrotor
{
public:
CClothes(CComponent* cpn):Decrotor(cpn){};
virtual void Operation();
};
void CClothes::Operation()
{
Decrotor::Operation();
cout<<"I have weared clothes"<<endl;
}
//安全删除指针宏
#define SAFE_DELETE_POINTER(p) /
if(p != NULL) /
delete p; /
p = NULL; /
cout<<p<<endl;
int main()
{
//相关指针定义
CComponent* peo = NULL;
CComponent* hdr = NULL;
CComponent* csd = NULL;
CComponent* clo = NULL;
//此处组合而成一个装饰后的对象
//生成相关对象的指针
peo = new CPeople;
hdr= new CHatDecrotor(peo);
csd = new CShoeDecrotor(hdr);
clo = new CClothes(csd);
//调用装饰完后的行为
clo->Operation();
//安全删除相关指针
SAFE_DELETE_POINTER(peo);
SAFE_DELETE_POINTER(hdr);
SAFE_DELETE_POINTER(csd);
SAFE_DELETE_POINTER(clo);
return 0;
}