设计模式(十五)装饰模式 C++
原创
©著作权归作者所有:来自51CTO博客作者油菜花11的原创作品,请联系作者获取转载授权,否则将追究法律责任
意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
好处就是把核心功能和装饰功能区分开来了
(要想真正理解装饰模式的代码实现,首先要理解多态的实现)
装饰模式主要包含以下角色。
- 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
- 具体构件(Concrete Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。
- 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
- 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
在下面的demo中,手机作为抽象构件,iPhone 和Nokia 作为具体构件,DecoratorPhone作为抽象装饰,
DecoratorPhoneA,DecoratorPhoneB作为具体装饰,一个代表挂件,一个代码贴膜。
装饰模式的技术思想是:通过多态性调用各个装饰
#include <iostream>
#include <windows.h>
using namespace std;
//公共抽象类
class Phone
{
public:
Phone()
{}
virtual ~Phone()
{}
virtual void ShowDecorate()
{}
};
//具体的手机类
class iPhone : public Phone
{
private:
string m_name; //手机名称
public:
iPhone(string name) : m_name(name)
{}
~iPhone()
{}
void ShowDecorate()
{
cout << m_name.c_str() << " 的装饰" << endl;
}
};
//具体的手机类
class NokiaPhone : public Phone
{
private:
string m_name;
public:
NokiaPhone(string name) : m_name(name)
{}
~NokiaPhone()
{}
void ShowDecorate()
{
cout << m_name.c_str() << " 的装饰" << endl;
}
};
//装饰类
class DecoratorPhone : public Phone
{
public:
DecoratorPhone(Phone *phone) : m_phone(phone)
{}
virtual void ShowDecorate()
{
m_phone->ShowDecorate();
}
private:
Phone *m_phone; //要装饰的手机
};
//具体的装饰类
class DecoratorPhoneA : public DecoratorPhone
{
public:
DecoratorPhoneA(Phone *phone) : DecoratorPhone(phone)
{}
void ShowDecorate()
{
DecoratorPhone::ShowDecorate();
AddDecorate();
}
private:
//增加的装饰
void AddDecorate()
{
cout << "增加挂件" << endl;
}
};
//具体的装饰类
class DecoratorPhoneB : public DecoratorPhone
{
public:
DecoratorPhoneB(Phone *phone) : DecoratorPhone(phone) {}
void ShowDecorate()
{
DecoratorPhone::ShowDecorate();
AddDecorate();
}
private:
//增加的装饰
void AddDecorate()
{
cout << "屏幕贴膜" << endl;
}
};
int main()
{
Phone *pNokia = new NokiaPhone("Nokia6300");
Phone *pPendant = new DecoratorPhoneA(pNokia); //装饰,增加挂件
Phone *pPatch = new DecoratorPhoneB(pPendant); //装饰,屏幕贴膜
pPatch->ShowDecorate();
delete pPendant;
delete pPatch;
delete pNokia;
system("pause");
return 0;
}