java - 使用列表而不是装饰器模式?

标签 java list oop design-patterns decorator

《Head First: Design Patterns》一书中的一个装饰模式用例让我产生了这个疑问。我会试着把它写下来:

It's a coffee shop system with some coffees and a lot of condiments you can put in them (for an extra cost), you need to be able to order and charge for a coffee with any condiments the costumer desires, and to avoid having total mayhem (e.g. booleans to keep track of the condiments) Decorator Pattern is used. We have an abstract Beverage class, each type of coffee as concrete components and each condiment as concrete decorators wrapping up a Beverage, like this:

Beverage Class Diagram

And so we have the following process returning a coffee cost:

Coffee Cost Delegation

我的问题是:为什么不用列表而不是装饰器来实现它?我们可以在每种饮料中都有一个调味品列表,并通过遍历列表来计算成本。要点一杯咖啡,我们只需要实例化一次并添加所需的调味品,避免像这样的声明:

// Using second image example
Beverage beverage = new DarkRoast(beverage);
beverage = new Mocha(beverage);
beverage = new Whip(beverage);

除此之外,我们将有更多的操作灵 active ,例如为不包括调味品的咖啡提供折扣,一旦我们不再需要装潢师来包装咖啡。这是一个经过长期研究的问题,我知道我遗漏了一些东西或者我可能做错了什么,所以如果您对此有任何想法,我很乐意了解并进一步讨论。

最佳答案

Decorator 模式是关于在运行时使用附加功能装饰(增强)对象。

假设您已经有一个类,我们称它为类A,它实现了一个接口(interface)IA。现在,如果需要添加一个附加功能,我们希望它有一个方法 someAlignFeatureToA(),而 A 中没有。现在您可以选择扩展类 A。另一种方法是 Composition,它应该优于 Inheritance。您可以将类 A 的对象包装在另一个类 B 中,实现与 A 相同的 InterfaceIA。这样对于客户端代码来说,很容易接受类 B 的对象,因为它具有与 A 相同的接口(interface)。(假设代码写得很好,这取决于抽象(接口(interface) IA ) 而不是像 class A 这样的具体类)。

这样继承链就不会太长,你可以很容易地在运行时添加额外的功能。

现在回答你的问题:是的,在你问题中的例子中,列表更合适,但我觉得作者的意图是用一个简单的例子来解释装饰器模式的用法. 假设咖啡由牛奶、咖啡混合物和糖组成。咖啡混合物进一步由更小的成分组成。这里出现了类似于复合模式的解决方案。

装饰器模式是基于行为增强的设计模式。 Java IO 流使用此行为(方法实现)由装饰类增强(一个流与另一个流包装以增强前一个流)

关于java - 使用列表而不是装饰器模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43565475/

相关文章:

c# - 对通用列表降序排序

C# - 接口(interface)说明

Java GUI 一直挂起

python - 继承、组合或其他——我应该在测试中对实用程序类进行子类化吗?

java - 将@Nullable 放在具有可为空返回类型的方法的何处?

c# - 如何在 C# 中正确锁定 List<String> getter

java - 修改.class文件

java - 添加原始 Int 而不是 Int 对象有任何风险吗?

java - 没有 if-else 的 Spring 限定符

java - org.hibernate.LazyInitializationException : failed to lazily initialize a collection of role during login in spring security