Skip to content

Latest commit

 

History

History
42 lines (30 loc) · 2.15 KB

装饰器.md

File metadata and controls

42 lines (30 loc) · 2.15 KB

装饰器 Decorator

背景

添加新的职责/操作时,如果用继承实现,随着继承的深度不断增加,同时继承的强耦合增加了系统复杂性;而另一种实现方式就是组合。 而且,有时候我们希望只是对某个具体对象添加新操作而非一个类,例如PS软件中的工具箱。

定义

[1]动态地给一**[2]对象添加一些[3]额外的职责**。就增加功能来说,该模式比生成子类更加灵活。装饰器又有一个别名:Wrapper。

难点 & 关键

  1. 动态
  • 组合来实现,但关键是为了能给一个构件对象动态地添加,让wrapper与构件类有相同的接口operation,即继承于同一父类Component。然后让wrapper获取包装的Component。

  • 具体wrapper的operation,先调用持有对象的operation,再增加新的职责。这样就能嵌套地调用一系列的操作。

  1. 对象

这里不是为类添加职责,而是对具体的构件对象——有实际的内存,所以在使用时要不断传递上一层对象,并且不能释放之前的(装饰了的)构件对象

要素

  • 相同的父类,一致的接口operation
  • wrapper中维护当前对象
  • wrapper的operation中先调用当前对象的操作,再添加新操作

优点

  • 拓展对象比继承更灵活;
  • 可以以一定顺序对一个对象多次装饰,创造出不同的行为组合,得到功能更加丰富的对象
  • 具体构件类和具体装饰类可以独立变化,用户可以拓展新的构件类和装饰类。

不足

  • 会产生许多小对象,大量小对象占据内存。
  • 易出错,出错时调试不便。

适用环境

  • 为已有对象添加新的功能;
  • 需要在对象的核心功能的基础上,添加一些额外的新功能。
  • 不能用生成子类的方式进行扩展时:
    1. 拓展有很多时,全部生成子类数量庞大,不如用装饰器对象,相对前者要小很多(但数量仍很大);
    2. 类定义被隐藏时。

例如: IO中的输入输出流、图形界面中的构件