在添加新的职责/操作时,如果用继承实现,随着继承的深度不断增加,同时继承的强耦合增加了系统复杂性;而另一种实现方式就是组合。 而且,有时候我们希望只是对某个具体对象添加新操作而非一个类,例如PS软件中的工具箱。
[1]动态地给一**[2]对象添加一些[3]额外的职责**。就增加功能来说,该模式比生成子类更加灵活。装饰器又有一个别名:Wrapper。
- 动态
-
用组合来实现,但关键是为了能给一个构件对象动态地添加,让wrapper与构件类有相同的接口operation,即继承于同一父类Component。然后让wrapper获取包装的Component。
-
具体wrapper的operation,先调用持有对象的operation,再增加新的职责。这样就能嵌套地调用一系列的操作。
- 对象
这里不是为类添加职责,而是对具体的构件对象——有实际的内存,所以在使用时要不断传递上一层对象,并且不能释放之前的(装饰了的)构件对象。
要素
- 相同的父类,一致的接口operation
- wrapper中维护当前对象
- wrapper的operation中先调用当前对象的操作,再添加新操作
- 拓展对象比继承更灵活;
- 可以以一定顺序对一个对象多次装饰,创造出不同的行为组合,得到功能更加丰富的对象;
- 具体构件类和具体装饰类可以独立变化,用户可以拓展新的构件类和装饰类。
- 会产生许多小对象,大量小对象占据内存。
- 易出错,出错时调试不便。
- 为已有对象添加新的功能;
- 需要在对象的核心功能的基础上,添加一些额外的新功能。
- 不能用生成子类的方式进行扩展时:
- 拓展有很多时,全部生成子类数量庞大,不如用装饰器对象,相对前者要小很多(但数量仍很大);
- 类定义被隐藏时。
例如: IO中的输入输出流、图形界面中的构件