装饰模式

装饰模式

Scroll Down

装饰模式动态地给一个对象添加一些额外的职责。单从增加功能的角度来说,装饰模式相比生成子类更为灵活

结构

decorator20190522081335290.jpg

参与者

  • Component(可动态添加职责的对象接口) — 装饰器和被装饰对象都需要实现这个接口

  • ConcreteComponent(被添加职责的具体对象) — 被添加职责的方法主要是Component中所定义的方法

  • Decorator(装饰ConcreteComponent的具体对象) — 和ConcreteComponent一样实现了Component接口 — 维持一个指向被装饰对象的引用(可以用于分离撤销装饰) — 将请求转发给被装饰的Component对象,并在转发请求前后执行一些附加的动作

优点

  1. 比静态继承更灵活 可以用添加和分离的方法灵活的增加和删除职责,在单继承语言中优势更明显
  2. 避免在层次结构高层的类有太多的特征 使用装饰对象可以逐渐的用简单的部件组合出复杂的功能,不会再一个高阶的类中展示出太多的特征,而是每一阶一个特征。

缺点

  1. 对象发生了改变 装饰不是继承,被装饰对象已经不是原来的对象了,原对象的继承链在被装饰时已经断裂,依赖对象标识的操作将会非常困难
  2. 产生了许多小对象 对于不了解系统的人来说,学习成本较高,很难快速使用好这些小装饰对象来自由定制功能

实现细节

  1. 接口一致性 装饰对象的接口必须与它所装饰的Component接口保持一致
  2. 省略抽象的Decorator类 使用该模式时往往是要处理现存的类层次结构而非设计一个系统,直接将Decorator向Component转发请求的职责合并到ConcreteDecorator中
  3. 保持Component类的简单性 被装饰类和装饰者都实现了Component类,如果它定义复杂,装饰的拓展就会变得非常局限,具体的子类拥有一些它们并不需要功能的可能性也会大大增加
  4. 改变对象的外壳而非改变对象内核 Decorator就像一个对象的外壳,包装了这个对象的行为而产生一个新的行为,而类似设计模式则是改变了对象的内核——直接改变了该对象的行为
  5. 当Component类原本就很庞大时不适合使用装饰模式,原因见3,使用策略模式直接改变该对象会好些。