在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰器模式来实现。
装饰器模式
允许向一个现有的对象添加新的功能,同时又不改变他的结构(进行扩展)。
装饰器模式的结构与实现
通常情况下,扩展一个类的功能会使用继承方式来实现。但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。如果使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能,这就是装饰器模式的目标。
结构
抽象构件(Component):定义一个抽象接口以规范准备接收附加责任的对象
具体构件(Concrete Component):实现抽象构件,通过装饰器角色为其添加一些职责
抽象装饰(Decorator):继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能
具体装饰(Concrete Decorator):实现抽象装饰的相关方法,并给具体构件对象添加附加的责任
实现
#include <iostream>
#include <string>
using namespace std;
//装饰器模式
class Phone
{
public:
Phone(){}
~Phone(){}
virtual void showDecorate(){}
};
class iPhone :public Phone
{
private:
string _name;
public:
iPhone(string name)
:_name(name)
{}
~iPhone(){}
void showDecorate()
{
cout << _name << "装饰器" << endl;
}
};
class NokiaPhone :public Phone
{
private:
string _name;
public:
NokiaPhone(string name)
:_name(name)
{}
~NokiaPhone(){}
void showDecorate()
{
cout << _name << "装饰器" << endl;
}
};
class DecoratorPhone :public Phone
{
private:
Phone* m_phone;
public:
DecoratorPhone(Phone *phone)
:m_phone(phone)
{}
virtual void showDecorate()
{
m_phone->showDecorate();
}
};
class DecoratePhoneA :public DecoratorPhone
{
public:
DecoratePhoneA(Phone *phone)
:DecoratorPhone(phone)
{}
void showDecorate()
{
DecoratorPhone::showDecorate();
AddDecorate();
}
private:
void AddDecorate()
{
cout << "增加挂件" << endl;
}
};
class DecoratePhoneB :public DecoratorPhone
{
public:
DecoratePhoneB(Phone* phone)
:DecoratorPhone(phone)
{}
void showDecorate()
{
DecoratorPhone::showDecorate();
AddDecorate();
}
private:
void AddDecorate()
{
cout << "增加屏膜" << endl;
}
};
void main()
{
Phone* phone = new NokiaPhone("6300");
Phone* phoneA = new DecoratePhoneA(phone);
Phone* phoneB = new DecoratePhoneB(phone);
phoneA->showDecorate();
phoneB->showDecorate();
delete phone; phone = NULL;
delete phoneA; phoneA = NULL;
delete phoneB; phoneB = NULL;
}
装饰器模式的优缺点
优点:
可以不用修改原有的接口,就可以实现新功能的添加
装饰者可以很方便的转换原有接口中的实现,可以给装饰者指定不同的ConcreteComponent实现不同的功能。
缺点:
复杂性增加,装饰者模式会导致许多小类的产生。
装饰器模式应用场景
前面讲解了关于装饰器模式的结构与特点,下面介绍其适用的应用场景,装饰器模式通常在以下几种情况使用。
当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。
当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰器模式却很好实现。
当对象的功能要求可以动态地添加,也可以再动态地撤销时。