动态地给一个对象添加一些额外的职责。
适用场景
1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2、处理那些可以取消的职责。
3、不能或不好采用生成子类的方法扩充职责。
就增加功能来说,装饰模式相比生成子类更为灵活。有时我们希望给某个对象而不是整个类添加一些功能。比如有一个手机,允许你为手机添加特性,比如增加挂件、屏幕贴膜等。一种灵活的设计方式是,将手机嵌入到另一对象中,由这个对象完成特性的添加,我们称这个嵌入的对象为装饰。这个装饰与它所装饰的组件接口一致,因此它对使用该组件的客户透明。
#include<iostream>
#include<cstring>
using namespace std;
class Phone
{
public:
virtual void ShowDecorate() = 0;
};
class iPhone : public Phone
{
public:
iPhone(string name):m_name(name){}
void ShowDecorate() {cout << m_name << "的装饰" << endl;}
private:
string m_name;
};
class NokiaPhone : public Phone
{
public:
NokiaPhone(string name):m_name(name){}
void ShowDecorate() { cout << m_name << "的装饰" << endl; }
private:
string m_name;
};
class DecoratorPhone : public Phone
{
public:
Phone * m_Phone;
public:
DecoratorPhone(Phone * phone):m_Phone(phone){}
virtual void ShowDecorate() { m_Phone->ShowDecorate(); }
};
class DecoratorPhoneA : public DecoratorPhone
{
public:
DecoratorPhoneA(Phone * phone):DecoratorPhone(phone){}
void ShowDecorate() {m_Phone->ShowDecorate(); AddDecorate(); }
void AddDecorate() { cout << "增加挂件" << endl; }
};
class DecoratorPhoneB : public DecoratorPhone
{
public:
DecoratorPhoneB(Phone * phone):DecoratorPhone(phone){}
void ShowDecorate() { m_Phone->ShowDecorate(); AddDecorate(); }
void AddDecorate() { cout << "屏幕贴膜" << endl; }
};
int main()
{
Phone *iphone = new NokiaPhone("6300");
Phone *dpa = new DecoratorPhoneA(iphone); //装饰,增加挂件
Phone *dpb = new DecoratorPhoneB(dpa); //装饰,屏幕贴膜
dpb->ShowDecorate();
delete dpa;
delete dpb;
delete iphone;
return 0;
return 0;
}
装饰模式提供了更加灵活的向对象添加职责的方式。可以用添加和分离的方法,用装饰在运行时刻增加和删除职责。装饰模式提供了一种“即用即付”的方法来添加职责。它并不试图在一个复杂的可定制的类中支持所有可预见的特征,相反,你可以定义一个简单的类,并且用装饰类给它逐渐地添加功能。可以从简单的部件组合出复杂的功能。