设计模式(9) 装饰器模式(DECORATOR)(一)

2014-11-24 02:55:16 · 作者: · 浏览: 3
问题聚焦: 有时候,希望某个类增加新功能的时候,往往会生成一个子类。 但是,这种方式有时候略显臃肿,其次,这种方法是静态的,不够灵活。 因此,针对这种给对象动态添加功能的需求,大牛们给出了本节的装饰器模式。

意图: 动态地给一个对下添加一些额外的职责。 就增加功能来说,装饰器模式比相比生成子类更加灵活。
别名: 包装器Wraper
动机: 给某个对象,而不是整个类,添加一些功能。 举一个例子: 一个图形用户界面工具箱。 要求:允许你对任意一个用户界面添加一些特性,如边框,或者一些行为,如窗口滚动。 继承机制:使用继承机制是添加功能的一种有效途径,从其他类继承过来的边框特性可以被多个子类的实例所使用。 继承机制的缺点:不够灵活,因为边框的选择是静态的,用户不能控制对组件加边框的方式和时机。 装饰器方式:将组件嵌入到另一个对象中,由这个对象添加边框。我们称这个嵌入的对象为装饰。 装饰器方式的特点:这个装饰与它所装饰的组件接口一致,因此它对使用该组件的客户透明。 装饰器方式的优点:透明性。它将客户请求转发给该组件,并且可能在转发前后执行一些额外的动作。同时,你可以递归地嵌套多个装饰,从而可以添加任意多的功能。 Demo:假定有一个对象TextView,它可以在窗口中显示正文。 需求:在需要的时候,添加滚动条(使用ScrollDecorator),或者添加一个粗黑边框(使用BorderDecorator)。 类之间的关系: \ \ 装饰的过程如下图所示: \ \ 可视对象的装饰器类图设计: \ \ VisualComponent描述可视对象的抽象类,定义了绘制和事件处理的接口。 Decorator的子类为特定功能可以自由地添加一些操作。 优点:客户通常不会感觉到装饰过的组件与未装饰组件之间的差异,也不会与装饰产生任何依赖关系。因为装饰器是被界面的其他对象所使用。而并不是客户直接使用。

适用性:
  • 一下情况使用装饰器模式:
  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
  • 处理那些可以撤销的职责
  • 当不能采用生成子类的方法进行扩充时。不能采用子类的情况有两种:可能有大量独立的扩展,为支持每一种扩展,导致子类数目爆炸性增长。另一种情况,类定义被隐藏,或类定义不能用于生成子类。 结构: \
    \ 参与者:
    • Component(VisualComponent):定义一个对象接口,可以给这些对象动态地添加职责
    • ConcreteComponent(TextView):定义一个对象,可以给这个对象添加一些职责
    • DecotatZ http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcqO6zqyz1tK7uPbWuM/yQ29tcG9uZW50ttTP87XE1rjV66OssqK2qNLl0ru49tPrQ29tcG9uZW50vdO/2tK71sK1xL3Tv9o8bGk+Q29uY3JldGVEZWNvcmF0b3KjqEJvcmRlckRlY29yYXRvcqOsU2Nyb2xsRGVjb3JhdG9yo6mjus/y1+m8/sztvNPWsNTwCtCt1/ejugpEZWNvcmF0b3K9q8frx/PXqreiuPjL/LXEQ29tcG9uZW50ttTP86OssqK/ycTc1NrX6reix+vH88ewuvPWtNDQ0rvQqbi9vNO1xLav1/ehowo8YnI+CgrQp7n7o7oKCjx1bD4KPGxpPrHIvrLMrLzMs9C4/MHpu+6jutPDzO2807rNt9bA67XEt723qKOs08PXsMrOxvfU2tTL0NDKsb/M1Pa807rNyb6z/daw1PChozxsaT6x3MPi1Nqy47TOveG5ubjfsuO1xMDg09DMq7bgtcTM2NX3o7rXsMrOxveyu7K7ytTNvNTa0ru49ri01NO/ybao1sa1xMDgyc/Wp7PWo6y2+MrHx+PP8tPa1Nq88rWltcTA4MnPzO2809K7z7XB0L/J0aG1xLmmxNyhozxsaT5EZWNvcmF0b3LT68v8tcRDb21wb25lbnSyu9K70fmjutewys7KsaOssrvSwMC1sbvXsMrOttTP87XE0rvQqczY1fehozxsaT7T0NDttuDQobbUz/Ojurvh09DQ7bbgv7TJz8ilwOAmIzIwMjg0O7XE0KG21M/zo6zV4tCpttTP8732vfbU2sv7w8e1xM/gu6XBrL3TtcS3vcq9yc/T0Mv5srvNrKGj1eLKx9ewys7G97XEyLG146GjCsq1z9ajugrKudPD17DKzsb3xKPKvcqx06bXotLi0tTPwry4teOjugoKPHVsPgo8bGk+vdO/2rXE0rvWwtDUo7rXsMrOxve21M/ztcS907/asdjQ69Pry/zL+dewys61xENvbXBvbmVudLXEvdO/2srH0rvWwrXEoaM8bGk+yqHC1LPpz/O1xERlY29yYXRvcsSjyr2jurWxvfbQ6NKqzO2809K7uPbWsNTwyrGjrMO709Cx2NKqtqjS5bPpz/NEZWNvcmF0b3LA4KGjPGxpPrGjs9ZDb21wb25lbnTA4LXEvPK1pdDUo7rOqrGj1qS907/atcTSu9bC0NSjrNfpvP66zdewys6x2NDr09DSu7j2uau5srXEQ29tcG9uZW50uLjA4KOs0vK0y7Gjs9bV4rj2wOC1xLzytaXQ1MrHutzW2NKqtcShozxsaT64xLHkttTP883iv8fT67jEseS21M/zxNq6y6O617DKzsb3vs3P67bUz/O1xM3iv8ejrLjEseS1xMrHttTP87XE0NDOqqO7tvi1sbG717DKzrbUz/O5/dPaxdO087rNuLTU08qxo6zXsMrOxve+zc/UtcPBprK7tNPQxMHLo6zV4sqxuvKjrLrzw+a74b3pydy1xFN0cmF0ZWd5xKPKvb/JxNzKx9K7uPa4/LrDtcTRodTxoaMKCgo8aHI+CrT6wuvKvsD9o7oKz8LD5rXEyr7A/aOsy7XD98jnus7Ktc/W0ru49tewys7G96GjCjxwcmUgY2xhc3M9"brush:java;">// 假定已经存在一个Component类VisualComponent class VisualComponent { public: VisualComponent(); virtual void Draw(); virtual void Resize(); //... ... }; // 我们定义VisualComponent的一个子类Decorator,将生成Decorator的子类以获取不同的装饰 class Decorator : public VisualComponent { public: Decorator(Visua