装饰器模式
1、装饰器模式的适用场景
装饰器模式适用于,为一个已有功能的类增加新的功能或职责。增加功能或职责通过在类中增加或修改也可以达到目的,但这种方式会违背开闭原则。当然还有一种方法也能达到扩展功能的目的即:通过子类继承的方式,但是如果后续继续增加功能的话,便要继续继承现有的类,如此就会使继承的层次越来越深,不利与代码的维护和可读性。故最好的方式便是通过装饰者模式来完成。
2、装饰器模式的关键实现点
1、被装饰者和装饰者需要继承同一基类。此处的装饰者一般继承为纯虚函数(不实现具体的装饰过程,由子类【具体的装饰者】来做具体实现)如此的目的是,可以有多种装饰者,而不是只有一种。
2、具体的装饰者中要维护一个被装饰者的对象的引用。
3、装饰器模式实例讲解
以下实例说明装饰者的装饰及调用流程,现有这么一个场景:被装饰者是一个女孩,装饰者是超短裙和黑丝
3.1、首先装饰者和被装饰者需要有一个共同的基类
class Base
{
public:
virtual void show()=0;
virtual ~Base(){};
std::string str;
};
3.2、装饰者需要继承自此基类
class Girl :public Base
{
public:
Girl()
{
str = "啥也没穿的女孩";
}
void show(){ std::cout << str.c_str() << std::endl; };
virtual ~Girl(){};
};
3.3、被装饰者以接口的形式继承自基类Base
class Decrator :public Base
{
protected:
Base* pBase; //维护一个被装饰者对象的引用(此处便为Girl的对象的引用)
public:
virtual void show() = 0;
virtual ~Decrator(){};
};
3.4、实际的装饰者实现:超短裙装饰
class MiniSkirt : public Decrator
{
public:
MiniSkirt(Base* pBase)
{
this->pBase = pBase;
}
void show()
{
this->str = pBase->str + "穿超短裙";
std::cout << str.c_str()<<std::endl;
};
virtual ~MiniSkirt(){};
};
3.5、实际的装饰者实现:黑丝装饰
class BlackSilk : public Decrator
{
public:
BlackSilk(Base* pBase)
{
this->pBase = pBase;
}
void show()
{
this->str = pBase->str + "穿黑丝";
std::cout << str.c_str()<<std::endl;
};
virtual ~BlackSilk(){};
};
3.6、调用代码为:
int main()
{
//原始的被装饰者
Girl *pGirl = new Girl();
pGirl->show(); //输出为啥也没穿的女孩
//装饰一个超短裙
MiniSkirt* pMiniSkirt = new MiniSkirt(pGirl);
pMiniSkirt->show();//输出为啥也没穿的女孩穿超短裙
//在装饰一下
BlackSilk *pBlackSilk = new BlackSilk(pMiniSkirt);
pBlackSilk->show();//输出为啥也没穿的女孩穿超短裙穿黑丝
return 0;
}