假设我们已经实现了装饰器模式,如下图所示。使用 CondimentDecorator 类,可以装饰 Beverage 类。方法cost()
和getDescription()
将照顾到这一点。
在创建如下所示的装饰 Beverage 时,调用 getName()方法不会对装饰对象起作用。为了使这项工作,这个方法也应放在 CondimentDecorator 类中,并将调用委托给组合的饮料变量。
Beverage b = new Milk(new Espresso("A very nice espresso"));
b.getName() // returns null
当有很多不需要装饰的方法时,所有这些方法也应放在 CondimentDecorator 中以简单委托。所以问题是:什么是解决这个问题的整洁(普遍接受)的方式'
答案 0 :(得分:1)
这个问题的普遍接受的方法&#39;在一个静态类型语言中,如Java或C#(是的,C#不是静态类型,我知道DLR和动态)是将装饰方法委托给装饰对象显式< / strong>即可。此解决方案具有简单和显式性的明显优势。
在您的示例中,如果您不重写getName
,则表示您想要更改已修饰对象的行为,这正是装饰器模式的目的
如果您选择默认委托装饰对象 ,那么看起来好像继承被破坏了,因为CondimentDecorator继承自Beverage但不使用基类方法。
然后,要改变这种行为,你会以某种方式需要定义未委托给装饰对象的方法,但是应该像通常的继承一样工作&#34;。 那不是很明显也很混乱。
话虽如此,你想要实现的目标应该是Java。
例如在.NET中你可以通过以下方式实现这一点,我相信Java有类似的东西
此外,请查看prototypical inheritance works in JavaScript -该行为与您尝试实现的行为非常相似的方式
答案 1 :(得分:0)
在您的情况下,如果只有少数operation1(),则可以向CondimentDecorator添加委托调用。如果只有少数call()需要装饰,那么可以在需要时制作装饰器,例如: DecoratorFactory.make(新牛奶(新浓缩咖啡(“非常好的咖啡”)))。getDescription();
或
CondimentDecorator.getDescription(新牛奶(新浓缩咖啡(“非常好的咖啡”)));
关键:模式为您服务。