- 分类:结构型模式
- 特点:装饰器模式可以在不改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
- 模式结构:
- UML图:略(后补)
- 组成
- Component(抽象构件):给出一个抽象接口,以规范准备接收附加责任的对象。
- ConcreteComponent(具体构件):定义一个将要接收附加责任的类。
- Decorator(抽象装饰类):持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。
- ConcreteDecorator(具体装饰类):负责给构件对象添加上附加的责任。
- 适用场景
- 需要扩展一个类的功能,或给一个类添加附加职责。
- 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
- 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
- 实例分析:
- 在星巴克购买咖啡时,可以选用不同种类的咖啡的同时,还可以要求在其中加入各种调味品(辅料)。(例如:奶油、摩卡、糖浆等)。倘若咖啡不带劲,我们想要添加奶油、摩卡和糖浆,这时,就可以利用装饰者模式思想来实现。
- 1、创建构件(定义饮料基类,提供名称和价钱)
//component.h
#ifndef __COMPONENT_H_
#define __COMPONENT_H_
#include<string>
using namespace std;
//饮料基类
class IBeverage
{
public:
virtual string Name() = 0;
virtual double Cost() = 0;
};
#endif //COMPONENT_H
2、创建具体构件(如有两款咖啡:黑咖啡和烘焙咖啡)
//concrete_component.h
#ifndef __CONCRETE_COMPONENT_H__
#define __CONCRETE_COMPONENT_H__
#include "component.h"
//***具体的饮料(咖啡)类
//黑咖啡
class HouseBlend : public IBeverage
{
public:
string Name() { return "HouseBlend"; }
double Cost() { return 30.0; }
};
//烘焙咖啡
class DarkRoast: public IBeverage
{
public:
string Name() { return "DarkRoast"; }
double Cost() { return 28.5; }
};
#endif //CONCRETE_COMPONENT_H
- 3、创建装饰器基类(有了coffee后,就要添加调味品,其同样继承 IBeverage,并持有咖啡的实例)
//decorator.h
#ifndef __DECORATOR_H__
#define __DECORATOR_H__
#include "component.h"
//调味品
class CondimentDecorator : public IBeverage
{
public:
CondimentDecorator(IBeverage* beverage) :m_pBeverage(beverage) {}
string Name() { return m_pBeverage->Name(); }
double Cost() { return m_pBeverage->Cost(); }
//note:是保护成员,不能是private,否则子类无法使用
protected:
IBeverage* m_pBeverage;
};
#endif //DECORATOR_H
- 4、创建具体装饰(添加不同调料)
#ifndef __CONCRETE_DECORATOR_H__
#define __CONCRETE_DECORATOR_H__
#include "decorator.h"
//奶油(调味品)
class Cream : public CondimentDecorator
{
public:
//构造函数,note:因为构造函数是不可继承的,需要调用父类构造函数对父类对象进行初始化
Cream(IBeverage* beverage) : CondimentDecorator(beverage) {}
string Name() { return m_pBeverage->Name() + " Cream"; }
double Cost() { return m_pBeverage->Cost() + 3.5; }
};
//摩卡
class Mocha : public CondimentDecorator
{
public:
Mocha(IBeverage* beverage) :CondimentDecorator(beverage) {}
string Name() { return m_pBeverage->Name() + " Mocha"; }
double Cost() { return m_pBeverage->Cost() + 2.0; }
};
//糖浆
class Syrup : public CondimentDecorator
{
public:
Syrup(IBeverage* beverage) :CondimentDecorator(beverage) {}
string Name() { return m_pBeverage->Name() + " Syrup"; }
double Cost() { return m_pBeverage->Cost() + 3.0; }
};
#endif //CONCRETE_DECORATOR_H
- 5、创建客户端(为coffee添加各种调味料)
//main.cpp
#include<iostream>
#include "concrete_component.h"
#include "concrete_decorator.h"
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) {if(p) delete(p); (p) = NULL;}
#endif
int main()
{
//黑咖啡
IBeverage* pHouseBlend = new HouseBlend();
cout << pHouseBlend->Name() << ":" << pHouseBlend->Cost() << endl;
//黑咖啡+奶油
CondimentDecorator* pCream = new Cream(pHouseBlend);
cout << pCream->Name() << ":" << pCream->Cost() << endl;
//黑咖啡+摩卡
CondimentDecorator* pMocha = new Mocha(pHouseBlend);
cout << pMocha->Name() << ":" << pMocha->Cost() << endl;
//黑咖啡+糖浆
CondimentDecorator* pSyrup = new Syrup(pHouseBlend);
cout << pSyrup->Name() << ":" << pSyrup->Cost() << endl;
//****烘烤咖啡
IBeverage* pDarkRoast = new DarkRoast();
cout << pDarkRoast->Name() << ":" << pDarkRoast->Cost() << endl;
//烘烤咖啡+奶油
CondimentDecorator * pCrameDR = new Cream(pDarkRoast);
cout << pCrameDR->Name() << ":" << pCrameDR->Cost() << endl;
//***********important***
//烘烤咖啡+奶油+摩卡
CondimentDecorator* pCreamMocha = new Mocha(pCrameDR);
cout << pCreamMocha->Name() << ":" << pCreamMocha->Cost() << endl;
//烘烤咖啡+奶油+摩卡+糖浆
CondimentDecorator* pCreamMochaSyrup = new Syrup(pCreamMocha);
cout << pCreamMochaSyrup->Name() << pCreamMochaSyrup->Cost() << endl;
//****important:注意顺序
SAFE_DELETE(pSyrup);
SAFE_DELETE(pMocha);
SAFE_DELETE(pCream);
SAFE_DELETE(pHouseBlend);
SAFE_DELETE(pCreamMochaSyrup);
SAFE_DELETE(pCreamMocha);
SAFE_DELETE(pCrameDR);
SAFE_DELETE(pDarkRoast);
system("pause");
return 0;
}
- 运行结果