Is the decorator pattern really needed here?
我正在从《头一设计模式书》学习装饰设计模式。他们的例子把不同类型的咖啡当作饮料。饮料上装饰有牛奶、大豆、鲜奶油等。例如,黑咖啡加摩卡和鲜奶油:
类图:
我理解这个例子的使用只是因为它很简单。但是,我有一种替代的、更简单的方法来实现这个不使用decorator模式的示例。我们可以有一个带有描述和成本的项目类。然后,饮料类可以有基本成本、总成本和项目列表。
这种替代设计比装饰图案有什么主要缺点吗?你能给我一些具体的场景吗,在这些场景中,装饰图案会比我的设计更好?
PS-如果有人想要查看装饰代码:https://github.com/bethrobson/head-first-design-patterns/tree/master/src/headfirst/designpatterns/decorator/starbuzz
这个例子主要是关于如何使用decorator模式
Patterns can be a complex subject and knowing when to use them is sometimes more complicated than understanding how to use them
其他示例如
1 2 3 4 5 6 7 8 9 10 11 12 |
这是使用decorator模式添加功能而不进行多重继承的主要原因。
The Decorator pattern provides a more flexible way to add responsibilities to objects than can be had with static (multiple) inheritance
在这里,一种特定的饮料基本上是由一个相关的成分列表来表示的。
在这个简单的例子中,它可能是可以的,但是如果有许多成分,可能有不同的数量,另一个数据结构可能会更好(可能是某种哈希表,但还有许多其他的可能性)。
例如,这里的数量是用重复的项目表示的(因此没有分数),例如,请参见starbuzcoffee.java中
您可以通过考虑管理另一个数据结构的开销,而不是链接列表的简单性,来决定哪个解决方案更好,记住,如果链接列表中有许多项,特别是需要对元素进行随机访问时,链接列表的成本可能很高。示例:您需要O(N)循环(其中N是列表大小)来检查饮料是否具有给定的成分,更不用说哈希表了。但是对于低n值,哈希表的解决方案可能会慢一些,因为它是一个更复杂的数据结构。
你的问题的答案取决于上下文,但一般来说,另一种方法没有错。
在这个例子中,在没有装饰器模式的情况下,可以有相同的行为。我同意别人已经说过的话。当然,这个例子只是为了学习如何与装饰师合作并识别模式。
我想在这里增加一点,我如何看待这个问题。(因为你说你在学习这个模式)
当您使用decorator模式时,它可能只做一些其他的实现。无论如何,好处是使用已知的模式,并且您有一个词来描述实现。通常,这在与团队合作时很重要,因为这样您就可以有效地描述实现细节。(当其他开发人员也知道模式时)
当您使用自己的方法来实现行为时,通常需要一些时间来讨论它是如何工作的。
第二个好处是装饰图案试图解决的问题。装饰图案-维基百科
- 职责应该在运行时动态地添加到对象(并从中删除)。
- 应提供扩展功能的灵活的子类化替代方案。
我之所以提到这一点,是因为使用模式在处理遗留代码/未知代码时非常有用。通常,您需要这种技巧来添加新的行为,而不修改原始实现。