要为一个类扩展功能,那么可以使用派生,然后由派生类实现扩展的功能。
但,若扩展的是个临时功能,或者可能扩展多个不确定功能,就需要使用装饰模式。装饰模式允许为一个类临时添加任意其他功能,并可以任意组合。
装饰模式可以在不生成子类的情况下为对象添加职责。
1. 定义Component类
该类是被装饰类与装饰类的共同基类。该类规定了被装饰类的操作接口。
class Component
{
public:
virtual void Operation() = 0;
protected:
Component();
};
2. 定义原始类
即需要被扩展的类。该类从Component类派生。
在实际应用中,该类的对象需要通过装饰类来添加额外功能。
class ConcreteComponent :public Component
{
public:
ConcreteComponent();
virtual void Operation();
};
3. 定义装饰类
装饰类用于扩展原始类。扩展后,装饰类将代替原始类。所以装饰类与原始类从同一个父类派生。
同时,为了保留原始类的功能,将原始类以组合的形式内嵌到装饰类中。
由于装饰可能有多种,所以从共同父类Component派生一个装饰类基类,然后由该基类再派生不同的装饰类。
//Decorator:装饰抽象类,继承自Component
class Decorator :public Component
{
public:
Decorator(Component* com)
{
this->_com = com;
};
void SetComponent(Component* com);
virtual void Operation();
protected:
Component* _com;
};
//装饰类A
class ConcreteDecoratorA :public Decorator
{
public:
ConcreteDecoratorA(Component* com);
void AddBehavorA();
virtual void Operation()
{
this->_com->Operation();
//附加职责A
this->AddBehavorA();
};
};
//装饰类B
class ConcreteDecoratorB :public Decorator
{
public:
ConcreteDecoratorB(Component* com);
void AddBehavorB();
virtual void Operation()
{
this->_com->Operation();
//附加职责B
this->AddBehavorB();
};
};
4. 用户使用
void main()
{
Component* pComponent = new ConcreteComponent(); //要装饰的对象
Decorator* pDecorator = NULL;
pDecorator = new ConcreteDecoratorA(pComponent); //附加职责A
pDecorator = new ConcreteDecoratorB(pDecorator); //附加职责B
pDecorator->Operation();
delete pDecorator;
}
由Dectorator模式的结构可知,每个Dectorator类都提供一个扩展功能。 如果需要多个扩展功能,可以进行多层嵌套。因为每个Dectorator类都是一个 Component,因此也可以被进一步嵌套为其他Dectorator类。