首页 > 代码库 > 装饰模式(Decorator)-- 对象结构型模式

装饰模式(Decorator)-- 对象结构型模式

1.动机

有时我们希望给某个对象而不是整个类添加一些功能。使用继承机制是添加功能的一种有效途径,从其他类继承过来的边框特性可以被多个子类的实例所使用。但这种方法不够灵活,因为边框的选择是静态的,用户不能控制对组件加边框的方式和时机。一种较为灵活的方式是将组件嵌入另一个对象中,由这个对象添加边框。我们称这个嵌入的对象为装饰

 

2.描述

这个装饰与它所装饰的组件接口一致,因此它对使用该组件的客户透明。它将客户请求转发给该组件,并且可能在转发前后执行一些额外的动作(例如画一个边框)。

Decorator类的子类为特定功能可以自由地添加一些操作。例如,如果其他对象知道界面中恰好有一个ScrollDecorator对象,这些对象就可以用ScrollDecorator对象的ScrollTo操作滚动这个界面。这个模式中有一点很重要,它使得在VisualComponent可以出现的任何地方都可以有装饰。因此,客户通常不会感觉到装饰过的组件与未装饰组件之间的差异,也不会与装饰产生任何依赖关系。

 

参与者:

  • Component (Visual Component)

    定义的对象接口基类

  • Concrete Component (TextView)

    基础的派生类

  • Decorator

    维持一个指向真正Component基类的指针,同时,自己作为Component的"特别"派生类,实现Component的所有方法

  • ConcreteDecorator

    真正实现特殊功能的装饰类,他在Component的基础上,附加一些新的功能AddedBehavior, 这些功能,在调用"原装"派生类前后被调用

 

红框部分,就是在不改变原有基类、派生类行为的基础上,增加了新功能的一组"旁路"派生类。在系统最终想要使用具有额外功能的Component时,实际上他会去创建一个"旁路"派生类ConcreteDecorator, 这个"旁路"的派生类既具有正统派生类的功能,在其上,还添加了额外功能:

Window->setCoents(textView);

è

Window->setContent(new BorderDecorator(textView));

 

3.适用性

  1. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  2. 当不能采用生成子类的方法进行扩充时。例如,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长,此时使用子类继承不妥;另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类,此时无法使用继承。

 

装饰模式最有用的地方在于,它可以在不影响调用者的前提下,给单个对象增加功能,即使是加了多级装饰,调用者也不用担心会受影响。