1、定义
1.1 标准定义
装饰模式(Decorator Pattern)是一种比较常见的模式,其定义如下:
Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide a flexiblealternative to subclassing for extending functionality.(动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。)
1.2 通用类图
● Component抽象构件
Component是一个接口或者是抽象类, 是定义我们最核心的对象, 就是最原始的对象。
注意:在装饰模式中,必然有一个最基本、最核心、最原始的接口或抽象类充当Component抽象构件。
● ConcreteComponent 具体构件
ConcreteComponent是最核心、最原始、最基本的接口或抽象类的实现,你要装饰的就是它。
● Decorator装饰角色
一般是一个抽象类,做什么用呢?实现接口或者抽象方法,它里面可不一定有抽象的方法呀,在它的属性里必然有一个private变量指向Component抽象构件。
● 具体装饰角色
ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰类, 你要把你最核心的、最原始的、最基本的东西装饰成其他东西。
2、实现
2.1 类图
Component是定义一个对象接口,可以给这些对象动态地添加职责。
ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。
Decorator为装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能。
要善于变通,如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。
同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。
2.2 代码
2.2.1 装饰类
//Decorator.h #ifndef _DECORATOR_H_ #define _DECORATOR_H_ //Component抽象类,定义该类对象的接口 class Component { public: virtual ~Component(); virtual void Operation()=0; protected: Component(); }; //ConcreteDecorator:具体的Component对象,可以给该对象动态 添加职责 class ConcreteComponent:public Component { public: ConcreteComponent(); ~ConcreteComponent(); virtual void Operation(); }; //Decorator:装饰抽象类,继承自Component class Decorator:public Component { public: Decorator(Component* com); void SetComponent(Component* com); virtual ~Decorator(); virtual void Operation(); protected: Component* _com; }; //ConcreteDecorator就是具体的装饰对象之一,起到给Component添加职责的功能 class ConcreteDecoratorA:public Decorator { public: ConcreteDecoratorA(Component* com); ~ConcreteDecoratorA(); virtual void Operation(); void AddBehavorA(); }; //ConcreteDecorator就是具体的装饰对象之二,起到给Component添加职责的功能 class ConcreteDecoratorB:public Decorator { public: ConcreteDecoratorB(Component* com); ~ConcreteDecoratorB(); virtual void Operation(); void AddBehavorB(); }; //ConcreteDecorator就是具体的装饰对象之三,起到给Component添加职责的功能 class ConcreteDecoratorC:public Decorator { public: ConcreteDecoratorC(Component* com); ~ConcreteDecoratorC(); virtual void Operation(); void AddBehavorC(); }; //ConcreteDecorator就是具体的装饰对象之四,起到给Component添加职责的功能 class ConcreteDecoratorD:public Decorator { public: ConcreteDecoratorD(Component* com); ~ConcreteDecoratorD(); virtual void Operation(); void AddBehavorD(); }; //只添加一种装饰,则不用抽象出装饰基类 class DecoratorOnlyOne:public Component { public: DecoratorOnlyOne(Component* com); ~DecoratorOnlyOne(); virtual void Operation(); void AddBehavor(); private: Component* _com; }; //如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。 //略 #endif
// Decorator.cpp #include "Decorator.h" #include <iostream> using namespace std; Component::Component(){} Component::~Component() { cout << "~Component" << endl; } ConcreteComponent::ConcreteComponent(){} ConcreteComponent::~ConcreteComponent() { cout << "~ConcreteComponent" << endl; } void ConcreteComponent::Operation() { cout << "原职责:ConcreteComponent::Operation" << endl; } Decorator::Decorator(Component* com) { this->_com = com; } void Decorator::SetComponent(Component* com) { this->_com = com; } Decorator::~Decorator() { cout << "~Decorator" << endl; delete this->_com; this->_com = NULL; } void Decorator::Operation(){} ConcreteDecoratorA::ConcreteDecoratorA(Component* com):Decorator(com){} ConcreteDecoratorA::~ConcreteDecoratorA() { cout << "~ConcreteDecoratorA" << endl; } void ConcreteDecoratorA::Operation() { this->_com->Operation(); //附加职责A this->AddBehavorA(); } void ConcreteDecoratorA::AddBehavorA() { cout << "附加职责A:ConcreteDecoratorA::AddBehavorA" << endl; } ConcreteDecoratorB::ConcreteDecoratorB(Component* com):Decorator(com){} ConcreteDecoratorB::~ConcreteDecoratorB() { cout << "~ConcreteDecoratorB" << endl; } void ConcreteDecoratorB::Operation() { this->_com->Operation(); //附加职责B this->AddBehavorB(); } void ConcreteDecoratorB::AddBehavorB() { cout << "附加职责B:ConcreteDecoratorB::AddBehavorB" << endl; } ConcreteDecoratorC::ConcreteDecoratorC(Component* com):Decorator(com){} ConcreteDecoratorC::~ConcreteDecoratorC() { cout << "~ConcreteDecoratorC" << endl; } void ConcreteDecoratorC::Operation() { this->_com->Operation(); //附加职责C this->AddBehavorC(); } void ConcreteDecoratorC::AddBehavorC() { cout << "附加职责C:ConcreteDecoratorC::AddBehavorC" << endl; } ConcreteDecoratorD::ConcreteDecoratorD(Component* com):Decorator(com){} ConcreteDecoratorD::~ConcreteDecoratorD() { cout << "~ConcreteDecoratorD" << endl; } void ConcreteDecoratorD::Operation() { this->_com->Operation(); //附加职责D this->AddBehavorD(); } void ConcreteDecoratorD::AddBehavorD() { cout << "附加职责D:ConcreteDecoratorD::AddBehavorD" << endl; } //**************只添加一种修饰****************** DecoratorOnlyOne::DecoratorOnlyOne(Component* com):_com(com) { } DecoratorOnlyOne::~DecoratorOnlyOne() { cout << "~DecoratorOnlyOne" << endl; delete this->_com; this->_com = NULL; } void DecoratorOnlyOne::Operation() { this->_com->Operation(); this->AddBehavor(); } void DecoratorOnlyOne::AddBehavor() { cout << "附加唯一职责:DecoratorOnlyOne::AddBehavor" << endl; }
2.2.3 调用
// main.cpp #include "Decorator.h" #include <iostream> using namespace std; int main() { Component* pCom = new ConcreteComponent(); //要装饰的对象 Decorator* pDec = NULL; pDec = new ConcreteDecoratorA(pCom); //给装饰对象附加职责A pDec = new ConcreteDecoratorB(pDec); //给装饰对象附加职责B pDec = new ConcreteDecoratorC(pDec); //给装饰对象附加职责C pDec = new ConcreteDecoratorD(pDec); //给装饰对象附加职责D pDec->Operation(); cout << "-------------------------------" << endl; //只添加一种修饰 Component* pCom1 = new ConcreteComponent(); DecoratorOnlyOne* pDec1 = new DecoratorOnlyOne(pCom1); pDec1->Operation(); cout << "-------------------------------" << endl; delete pDec; cout << "-------------------------------" << endl; delete pDec1; return 0; }
2.2.4 运行结果
3、优缺点
3.1 优点
● 装饰类和被装饰类可以独立发展,而不会相互耦合。换句话说,Component类无须知道Decorator类,Decorator类是从外部来扩展Component类的功能,而Decorator也不用知道具体的构件。
● 装饰模式是继承关系的一个替代方案。我们看装饰类Decorator,不管装饰多少层,返回的对象还是Component,实现的还是is-a的关系。
● 装饰模式可以动态地扩展一个实现类的功能,这不需要多说,装饰模式的定义就是如此 。
3.2 缺点
对于装饰模式记住一点就足够了:多层的装饰是比较复杂的。为什么会复杂呢?你想想看,就像剥洋葱一样,你剥到了最后才发现是最里层的装饰出现了问题,想象一下工作量吧,因此,尽量减少装饰类的数量,以便降低系统的复杂度。
4、应用场景
● 需要扩展一个类的功能, 或给一个类增加附加功能。
● 需要动态地给一个对象增加功能, 这些功能可以再动态地撤销。
● 需要为一批的兄弟类进行改装或加装功能, 当然是首选装饰模式。