更新:因为我们通常会说,“情况将决定任何设计模式是否适合这项工作”...将使用装饰器解决现实生活中的咖啡订购系统图案?
装饰器模式是否太过于实施咖啡订购系统? Head First Design Patterns一书以它为例,但我想我会用2个数组或表来实现它:
咖啡类型(法式烤肉,家庭混合等)
另外(焦糖,奶油,肉桂等)
因此它可以是price.php中的2个数组,或DB中的2个数组,并读入2个数组。
当客户订购咖啡时,选择将总结价格。
看起来使用装饰器模式是相当矫枉过正的,或者你认为有充分的理由实际使用这种模式?作为一个例子,我认为它很好,但是如果它看起来像一个现实生活中的问题,它可以用一种简单的方法完全解决,但是使用更复杂的解决方案也会感觉很奇怪。
答案 0 :(得分:5)
这是高级抽象示例的典型问题。这个例子必须足够简单,易于理解和演示概念,这也意味着很多设计模式也更容易以另一种方式实现。
那就是说,我通常看到装饰器描述的方式是在窗口系统中。您有一个标准窗口,并且您希望允许窗口水平和垂直滚动。您可以为窗口子类化所有可能的变体,或者您可以提供一个水平滚动条装饰器和一个执行任务的垂直滚动条装饰器,并且具有额外的好处,您可以随后装饰其他控件,而无需子类甚至更多。这对我来说是一个非常有效的用于装饰器的设计,但是提供示例代码要困难得多。
答案 1 :(得分:2)
问题是,“它真的会”没有特别的答案。取决于程序员。编写简短示例的人可以提出他们喜欢的任何模式,但只有当您知道系统的其余部分才能决定结构时。
我相信,当你提供一个名称的东西时,它就变成了你需要学习的的东西,就像梯形规则 - 我认为实际上只是你知道这个领域的常识。不要将装饰器模式视为一种独立于工具的东西,它只是实现所需功能的一种方式。如果计数器类包装了一个Integer,那是装饰器模式,还是我们不关心?
Id使用“设计模式”作为指南/想法,以您能想到的最明智的方式对其进行编码。试着忘记他们的名字 - 只是让学习模式改进你的编程。 (但在面试前再看一遍!)
答案 2 :(得分:0)
他们正在尝试教授这个概念,而不是如何创建咖啡订购系统。装饰器模式用于更复杂的情况,如UI。
装饰器模式可以在诸如Java IO系统之类的地方使用。 BufferedReader是Reader的装饰器。
这种模式非常有用,并且有些地方可以很好地使用它。
答案 3 :(得分:0)
与其他人提到的一样,所解释的原理可能会因书籍所需的简单示例而丢失,但在现实世界中,当您编写更大更复杂的系统时,该模式将是可维护性的更好选择。 / p>
我认为示例中缺少的是装饰器模式是关于添加行为的。在第一个例子中,行为是计算成本。
假设按照您描述的方式使用数组实现类,然后总计成本。那没关系,你可以这样做,总计咖啡和浇头的成本。但是,现在说政府对咖啡征收高额税,因为他们认为咖啡因对你有害,他们希望人们减少饮酒。现在,您如何将饮税计算添加到饮料中?你绝对不想修改原始类,因为这会违反开放/封闭原则。您也可以扩展课程并添加行为,但这意味着您可能需要扩展您商店中含有咖啡因的所有食物/饮料的课程。这将变成一团糟,你可能会有很多课程要扩展。最后一个选项是使用装饰器模式并将税收计算行为动态添加到您想要的任何内容。这样就可以在不违反开放/封闭原则的情况下解决问题,或者可能延长可能数十个类别的噩梦。
这就是装饰者模式的内容。