设计模式十:decorator(装饰)——对象结构型模式
decorator(装饰)——对象结构型模式
1.意图
动态地给一个对象添加一些额外的职责,就功能来说,decorator比生成子类更灵活
2.别名
包装器wrapper
3.动机
有时候我们希望给某个对象而不是整个类添加一些功能。
使用继承机制是添加功能的一种有效途径,但是不够灵活,因为用户不能控制对组件增加功能的时机和方式。
一种比较灵活的方式就是把一个组件嵌入到另一个对象中,由这个对象来增加新的功能。
我们称这个嵌入的对象为装饰,这个装饰与他所装饰的组件接口一致,因此它对使用该组件的客户透明。它将客户的请求转发给该组件,并且可能在转发前后执行一些额外的动作。透明性可以使你递归嵌套多个装饰。
4.适用性
1)在不影响其他对象的情况下,以动态透明的方式给单个对象添加职责。
2)处理那些可以撤销的职责
3)当不能采用生成子类的方式进行扩充时
一种情况是可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类的数目成爆炸性增长。
另一种情况是因为类定义被隐藏,或者类定义不能用于生成子类。
5.结构

参考:http://www.cnblogs.com/babyzone2004/archive/2010/09/15/1826906.html
6.参与者
component
定义一个对象接口,可以给这些对象动态地添加职责
concreteComponent
定义一个对象,可以给这个对象添加一些职责
Decorator
维持一个指向component的指针,并定义一个与component接口一致的接口
concreteDecorator
向组件添加职责
7.协作
decorator将请求转发给它的component对象,并且有可能在转发请求前后执行一些附加的动作
8.效果
有两个优点和两个缺点
1)比静态继承更灵活
2)避免在层次结构高层的类有太多的特征
可以在decorator上一点一点的增加功能
3)decorator和它的component不一样
一个被装饰的组件和这个组件还是有差别的
4)有许多小对象
这些对象仅仅在他们互相连接的方式上有所不同,而不是他们的类或者是他们的属性值有所不同
9.实现
要注意的地方
1)接口的一致性
所有的concreteDecorator必须有一个公共的父类
2)省略抽象的decorator类
当你仅添加一个职责时,没有必要定义抽象的decorator类
3)保持component类的简单性
为保证接口的一致性,组件和装饰必须有一个公共的component父类。因此保持这个类的简单性是很重要的
4)改变对象外壳和改变对象内核
可以将decorator看成是对象的外壳,可以改变这个对象的行为。另外一种是改变对象的内核,比如strategy
10.代码示例
#include<iostream> using namespace std; class component { public: virtual void show(){} }; class concreteComponent:public component { public: void show() { cout<<"concrete component"<<endl; } }; class concreteComponentB:public component { public: void show() { cout<<"another concrete component called BBBB"<<endl; } }; class decorator:public component { public: decorator(component *co) { c = co; } void show() { c->show(); cout<<"decorator call show"<<endl; } private: component *c; }; class concreteDecoratorA:public decorator { public: concreteDecoratorA(component *co):decorator(co){} void show() { decorator::show(); cout<<"adding decorator A"<<endl; } }; class concreteDecoratorB:public decorator { public: concreteDecoratorB(component *co):decorator(co){} void show() { decorator::show(); cout<<"adding decorator BBBBB"<<endl; } }; int main() { component *conc = new concreteComponent(); component *d = new concreteDecoratorA(conc); d->show(); cout<<endl; conc = new concreteComponentB(); component *cd = new concreteDecoratorA(conc); cd->show(); cout<<endl; component *comp = new concreteDecoratorB(conc); comp->show(); }
11.相关模式
adapter:
decorator和adapter不同,因为装饰仅改变对象的职责而不改变对象的接口,而适配器改变了对象的接口
composite:
可以将装饰器看成一个退化的,仅有一个组件的组合,然而装饰器仅给对象增加一些新的职能,他的目的不在于对象的聚集
strategy:
用一个装饰你可以改变对象的外表,而strategy模式使你可以改变对象的内核,这是改变对象的两种途径。
浙公网安备 33010602011771号