装饰模式(Decorator),动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
结构图如下:
下面就使用一个具体的代码来举例子:我们假设要做一个手机,首先创建一个手机基类,实现手机的通用基本功能,Phone类就相当于Component;然后不同的手机类型实现其具体的功能,Nokia类和iPhone类就相当于ConcreteDecorator类;DecoratorStyle1和DecoratorStyle2是手机的装饰,就相当于ConcreteDecorator;
class Decorator : public Phone
{
public:
Decorator(Phone* phone);
virtual ~Decorator();
virtual void ShowDecorator();
private:
Phone* m_phone;
};
//具体的装饰类
class DecoratorStyle1 : public Decorator
{
public:
DecoratorStyle1(Phone* phone);
virtual ~DecoratorStyle1();
void ShowDecorator();
private:
void AddDecorator();
};
class DecoratorStyle2 : public Decorator
{
public:
DecoratorStyle2(Phone* phone);
virtual ~DecoratorStyle2();
void ShowDecorator();
private:
void AddDecorator();
};
Decorator::Decorator(Phone* phone) : m_phone(phone)
{
}
Decorator::~Decorator()
{
}
void Decorator::ShowDecorator()
{
m_phone->ShowDecorator();
}
DecoratorStyle1::DecoratorStyle1(Phone* phone) : Decorator(phone)
{
}
DecoratorStyle1::~DecoratorStyle1()
{
}
void DecoratorStyle1::ShowDecorator()
{
Decorator::ShowDecorator();
AddDecorator();
}
void DecoratorStyle1::AddDecorator()
{
cout << "增加挂件" << endl;
}
DecoratorStyle2::DecoratorStyle2(Phone* phone) : Decorator(phone)
{
}
DecoratorStyle2::~DecoratorStyle2()
{
}
void DecoratorStyle2::ShowDecorator()
{
Decorator::ShowDecorator();
AddDecorator();
}
void DecoratorStyle2::AddDecorator()
{
cout << "屏幕贴膜" << endl;
}
然后main函数是
如上所示:每个装饰对象的实现和如何使用这个对象是分开的,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。当然如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。
装饰模式是为已有功能动态的添加更多功能的一种方式。一般情况下,如果是为了满足一些只在某种特定情况下才会执行的特殊行为的需要,如果是向旧的类中添加新的代码,那么会引入新的字段,新的功能和新的逻辑,从而增加了旧类的复杂度,这时装饰模式就提供了一个很好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象,因此当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择的、按顺序的使用装饰功能包装对象了。