2009-06-10 14 views
1

更新:由于我们通常会说,“情况将决定任何设计模式是否适合这项工作......”现实生活中的咖啡订购系统是否可以使用装饰模式解决?实施咖啡订购系统时装饰者模式是否过多?

实施咖啡订购系统时装饰者模式是否过多?该Head First设计模式书使用它作为一个例子,但我想我会只使用2个数组或表来实现它:

咖啡类型(法国烤,房子混合等)
另外(焦糖,奶油,肉桂等)

所以它可以是一个price.php中的2个数组,或者DB中的2个表,并读入2个数组。

当顾客订购咖啡时,选择将总结价格。

它看起来像使用装饰模式是相当矫枉过正,或者你认为有充分的理由实际使用这种模式?作为一个例子,我认为这很好,但是如果它看起来像一个真正的生活问题,它可以通过一种简单的方式完全解决,但也可以用一个更复杂的解决方案,它也会感到很奇怪。

回答

5

这是一个典型的高级抽象示例问题。这个例子必须足够简单,以便于理解和展示概念,这也意味着大量的设计模式可以以其他方式更容易地实现。

这就是说,我通常看到的装饰者描述的方式是在窗口系统中。你有一个标准的窗口,你希望允许窗口水平和垂直滚动。您可以为窗口创建所有可能的变体的子类,或者您可以提供一个水平滚动条装饰器和一个垂直滚动条装饰器来执行任务,并且还可以装饰其他控件,而无需甚至子类化更多。对我来说,这对装饰者来说是非常有效的用途,它可以让人们了解各种想法,但要为其提供示例代码要困难得多。

+0

+1。 Decorator模式有很好的用途,但Coffee Shop示例似乎只是一个说明性示例,而不是一个工作示例。 – micahtan 2009-06-10 22:41:43

2

问题是,“它真的会”没有特别的答案。取决于程序员。编码简短例子的人可以想出他们喜欢的任何模式,但只有当你知道系统的其他部分时,才能决定结构。

我相信,当你给的东西,就变成了事情,你必须去学习,像梯形规则 - 我认为这其实只是你知道的领域常识之一。不要把装饰模式看作是一种自身作为工具的东西,它只是实现所需功能的一种方式。如果一个计数器类包装一个Integer,是一个装饰器模式,还是我们不关心?

使用设计模式作为指南/想法,以最明智的方式编写代码。试着忘记他们的名字 - 只要让这些模式能够改善你的编程。 (但在面试前再次查看他们)

+1

忘记名称可以消除设计模式的关键元素之一 - 能够传达您正在使用的名称。我宁愿说'我已经使用这些窗口控件的装饰模式',而不是启动我对实现装饰器所做的描述。 – workmad3 2009-06-10 22:30:54

0

他们正在试图传授这一概念,而不是如何创建咖啡订购系统。装饰者模式使用的是更复杂的情况,如UI。

装饰模式可以用在诸如Java IO系统的地方。 BufferedReader是Reader的装饰器。

这种模式是非常有用的,有些地方它发现很好用。

0

与其他人一样,被解释的原理可能会失去一本书所需的简单示例,但在现实世界中,当您编写更复杂的系统时,该模式将是更好的可维护性选择。

我认为你在示例中缺少的一点是装饰者模式是关于添加行为。在头一个例子中,行为正在计算成本。

假设类按照您描述的方式实施,使用数组,然后总计成本。这很好,你可以这样做,并且总计咖啡和浇头的成本。但是,现在说政府对咖啡征收重税,因为他们认为咖啡因对你不利,而且他们希望人们少喝酒。现在你打算如何将税款计算添加到饮料中?你绝对不想修改原来的类,因为这会违反开放/封闭的原则。您也可以延长课程并添加行为,但这意味着您可能需要延长包含咖啡因的商店中所有食品/饮料的课程。这会变成一团糟,你可能会有很多类可以扩展。最后一个选项是使用装饰者模式,并将税收计算行为动态添加到您想要的任何内容。这样可以解决问题,而不会违反开放/封闭原则,或者延长可能的几十个课程的噩梦。

这就是装饰模式的意义所在。