一、使用场景
咖啡店里咖啡中可以加不同的配料–摩卡、牛奶、糖、奶泡;不同的饮品加上不同的配料有不同的价钱,怎样实现呢?
可能你的第一印象会想到使用继承,
1. 首先定义一个咖啡基类
2. 对于加糖的,加牛奶的,加摩卡的 ,加奶泡的,分别写一个子类继承
3. 对于加糖,又加奶的写一个类,对于对于加糖,又摩卡的写一个类,对于对于加糖、又奶泡的写一个类,对于加糖,又加奶、摩卡的写一个类
说到这里,你会发现这里四种配料就要写十几种实现类了,那如果我们的配料是二十几种或者三十几种呢,那么使用继承这种 方式肯定会使我们的子类爆炸,那要怎样解决你,答案就是使用装饰者模式
上文转载自:https://blog.csdn.net/qq_29130945/article/details/81114052?spm=1001.2014.3001.5501
Q:为什么装饰器模式可以解决此问题呢?
A:因为在基类component的子类中抽象出了装饰器(Decrator)基类,并在这个基类下面添加了多个装饰子类,就像上文中的(糖、牛奶、奶泡等)这样调用的时候就可以任意组合添加什么配料了。由此便不需要产生多种组合的子类。
二、定义
装饰器模式:实现了动态的给对象添加职能。
三、UML图
其中Decrator类就是装饰类基类,在装饰类基类的子类中就是用来添加辅料。
四、C++代码具体实现
例子:原生蛋糕,加奶油以及巧克力的例子。
#ifndef COMPONENT_H_
#define COMPONENT_H_
#include <iostream>
//定义一个原始的抽象类蛋糕,装饰器的功能是给蛋糕加上各种装饰,如奶油,巧克力,瓜子仁,花生米等
class Cake
{
public:
virtual void showCake()=0;
virtual ~Cake(){};
std::string name;
};
class ConcreteCake :public Cake
{
public:
ConcreteCake()
{
name = "原始蛋糕";
}
void showCake(){ std::cout << name.c_str() << std::endl; };
virtual ~ConcreteCake(){};
};
#endif
decorator.h文件描述具体的装饰器的类
#include "Component.h"
class CakeDecrator :public Cake
{
protected:
Cake* pCake; //维护一个Cake对象的引用,为Cake对象添加装饰
public:
virtual void showCake() = 0;
virtual ~CakeDecrator(){};
};
class CakeDecratorMilk : public CakeDecrator
{
public:
CakeDecratorMilk(Cake* pCake)
{
this->pCake = pCake;
}
void showCake()
{
this->name = pCake->name + "加奶油";
std::cout << name.c_str()<<std::endl;
};
virtual ~CakeDecratorMilk(){};
};
class CakeDecratorCholate : public CakeDecrator
{
public:
CakeDecratorCholate(Cake* pCake)
{
this->pCake = pCake;
}
void showCake()
{
this->name =pCake->name + "加巧克力";
std::cout << name.c_str() << std::endl;
};
virtual ~CakeDecratorCholate(){};
};
客户端代码:
#include "Decrator.h"
int main()
{
ConcreteCake *pConCake = new ConcreteCake();
pConCake->showCake();
CakeDecratorMilk* pDecMilk = new CakeDecratorMilk(pConCake);
pDecMilk->showCake();
CakeDecratorCholate *pDecCho = new CakeDecratorCholate(pDecMilk);
pDecCho->showCake();
delete pConCake;
delete pDecMilk;
delete pDecCho;
return 0;
}