(32)23种设计模式研究之三【装饰者模式】

一:定义

装饰者模式通过组合的方式扩展对象的特性,这种方式允许我们在任何时候对对象的功能进行扩展甚至是运行时扩展,而若我们用继承来完成对类的扩展则只能在编译阶段实现,所以在某些时候装饰者模式比继承(inheritance)要更加灵活。

装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

二:

装饰者模式具有的一些特征

1,装饰者(decorator)和被装饰(扩展)的对象有着相同的超类(supertype)。

2,我们可以用多个装饰者去装饰一个对象。

3,我们可以用装饰过的对象替换代码中的原对象,而不会出问题(因为他们有相同的超类)。

4,装饰者可以在委托(delegate,即调用被装饰的类的成员完成一些工作)被装饰者的行为完成之前或之后加上他自己的行为。

5,一个对象能在任何时候被装饰,甚至是运行时。

装饰模式其实就是一个包装器,并且是从里到外一层一层的包,是有先后顺序的。同时,各种不同装饰器的组合,可以组合出完全不同的效果来。这种链式的包裹方式又叫作—— 装饰链

你可以想想Windows中的字体设定——装饰模式  ,这就是一个模式应用的好例子,你可以对字体加粗,倾斜,改字体,改字号,所有单独的功能包裹到一起就合成了这样的字体。

装饰模式是一个为已有功能的类动态添加更多功能的一种方式,各个功能的扩展相互独立,可以根据需要随意组合,但组合的顺序有先后。

  优点:

  1.有效避免了继承方式对扩展对象功能带来的灵活性差的问题

  2.通过组合而非继承的方式,实现了动态扩展对象的功能的能力

  3.符合高内聚、低耦合的设计思想

  

  缺点:

  1.装饰链不能过长,否则影响效率

  2.原始类接口不能改变,因为所有装饰器基类继承于原始类接口,类接口变化会导致所有装饰器的修改

三:

装饰者与适配者模式的区别

编辑
1.关于新职责:适配器也可以在转换时增加新的职责,但主要目的不在此。装饰者模式主要是给被装饰者增加新职责的。
2.关于原接口:适配器模式是用新接口来调用原接口,原接口对新系统是不可见或者说不可用的。装饰者模式原封不动的使用原接口,系统对装饰的对象也通过原接口来完成使用。(增加新接口的装饰者模式可以认为是其变种--“半透明”装饰者)
3.关于其包裹的对象:适配器是知道被适配者的详细情况的(就是那个类或那个接口)。装饰者只知道其接口是什么,至于其具体类型(是基类还是其他派生类)只有在运行期间才知道。

  四、装饰者模式的优缺点                                                                                                   

  优点

           1、装饰者模式可以提供比继承更多的灵活性

           2、可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。

           3、通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。

           4、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

 缺点

           1、会产生很多的小对象,增加了系统的复杂性

           2、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

 、装饰者模式的适用场景                                                                                              

                 1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

                 2、需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。  当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。

 

六、总结                                                                                                                          

                 1、 组合和委托可以在运行时动态的添加新的行为,而继承是静态的,在系统编译时就已经决定了对象的行为。

                 2、装饰者模式意味着一群装饰者类,这些类用来包装具体组件

                 3、装饰者可以在被装饰者的行为前面或者后面加上自己的行为,甚至可以将被装饰者的行为整个取代掉,从而达到特定的目的。

                 4、可以用多个装饰者包装一个组件。

                 5、装饰者一般对于组件的客户是透明的,除非客户程序依赖于组件的具体类型。

                 6、装饰者会导致设计中出现许多的小对象,如果过度的使用,会让系统变得更加复杂。

                 7、装饰者和被装饰者对象有相同的超类型。

原文地址:https://www.cnblogs.com/wycBlog/p/7416939.html