📜  装饰者模式 |套装 2(介绍和设计)

📅  最后修改于: 2021-09-10 02:43:00             🧑  作者: Mango

正如我们所看到的,我们之前使用继承的设计效果不佳。在这篇文章中,装饰者模式是针对上一组中的设计问题讨论的。

所以我们现在要做的是在运行时拿一个比萨并用浇头“装饰”它:

  1. 拿一个披萨对象。

piz1

  1. 用辣椒对象“装饰”它。

piz2

  1. 用 CheeseBurst 对象“装饰”它。 piz3
  2. 调用 getCost() 并使用委托而不是继承来计算浇头成本。
    装饰模式

我们最终得到的是一个带有芝士碎和辣椒配料的比萨饼。可视化“装饰器”对象,如包装器。以下是装饰器的一些属性:

  • 装饰器与它们所装饰的对象具有相同的超类型。
  • 您可以使用多个装饰器来包装一个对象。
  • 由于装饰器具有与对象相同的类型,我们可以传递装饰对象而不是原始对象。
  • 我们可以在运行时装饰对象。

定义:

装饰器模式动态地将额外的职责附加到对象上。装饰器提供了一种灵活的替代子类来扩展功能。

类图: piz5图片来源:维基百科

  • 每个组件都可以单独使用,也可以由装饰器包装。
  • 每个装饰器都有一个实例变量,用于保存对其装饰的组件的引用(HAS-A 关系)。
  • ConcreteComponent 是我们要动态装饰的对象。

好处:

  • 装饰器模式可用于在运行时扩展(装饰)某个对象的功能
  • 装饰器模式是子类化的替代方案。子类化会在编译时添加行为,更改会影响原始类的所有实例;装饰可以在运行时为单个对象提供新的行为。
  • Decorator 提供了一种即用即付的方法来增加职责。与其试图在一个复杂的、可定制的类中支持所有可预见的特性,您可以定义一个简单的类并使用 Decorator 对象逐步添加功能。

缺点:

  • 装饰器会使实例化组件的过程复杂化,因为您不仅要实例化组件,还要将它包装在许多装饰器中。
  • 让装饰器跟踪其他装饰器可能很复杂,因为回顾装饰器链的多个层会开始将装饰器模式推到其真正意图之外。

参考:

  • Head First 设计模式(书籍)
  • https://neillmorgan.wordpress.com/2010/02/07/decorator-pattern-pros-and-cons/
  • https://en.wikipedia.org/wiki/Decorator_pattern
  • http://stackoverflow.com/questions/4842978/decorator-pattern-versus-sub-classing

在下一篇文章中,我们将讨论装饰器模式的实现。