当我装饰物体时,变量重置为默认值
我正在努力学习Decorator设计模式。 在这个例子中,我创建了一个应用程序,根据咖啡的类型(意式浓缩咖啡,咖啡豆,混合咖啡),大小(高,大,通风)和调味品装饰(大豆,奶油,蒸牛奶) - 为简洁起见,排除一些代码。
从底部的输出中可以看到,如果setSize(GRANDE)并不包装对象,getSize()将返回GRANDE。
如果我设置了大小(GRANDE),然后修饰该对象,则getSize()返回TALL(在Beverage类中设置的默认值)。
如果我setSize(GRANDE),装饰对象,setSize(GRANDE),然后getSize()返回GRANDE。
注意:虽然尺寸打印不正确,但成本计算正确。
问题:有没有一种方法可以对它进行编码,所以当我设置了Size()时,即使在装饰对象后它仍然保持该值。
package coffee;
public abstract class Beverage {
String description = "Unknown Beverage";
public enum Size { TALL, GRANDE, VENTI };
Size size = Size.TALL;
public String getDescription() {
return description;
}
public void setSize(Size size) {
this.size = size;
}
public Size getSize() {
return size;
}
public abstract double cost();
}
package coffee;
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
package coffee;
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "House Blend Coffee";
}
public double cost(){
return .89;
}
}
package coffee;
public class Soy extends CondimentDecorator {
Beverage beverage;
public Soy(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Soy";
}
public double cost() {
double cost = beverage.cost();
if( beverage.getSize() == Size.TALL) {
cost += .10;
} else if( beverage.getSize() == Size.GRANDE) {
cost += .15;
}else if( beverage.getSize() == Size.VENTI) {
cost += .20;
}
return cost;
}
}
package coffee;
import coffee.Beverage.Size;
public class StarbuzzCoffeeController {
public static void main(String[] args) {
Beverage beverage = new HouseBlend();
System.out.println( beverage.getSize() + " " + beverage.getDescription() + " $" + String.format("%.2f", beverage.cost() ));
beverage.setSize(Size.GRANDE);
System.out.println( beverage.getSize() + " " + beverage.getDescription() + " $" + String.format("%.2f", beverage.cost() ));
System.out.println("-----------------------");
Beverage beverage2 = new HouseBlend();
beverage2.setSize(Size.GRANDE);
System.out.println( beverage2.getSize() + " " + beverage2.getDescription() + " $" + String.format("%.2f", beverage2.cost() ));
如果我不跟着另一个setSize(),它会在下一行打印“TALL”作为大小:
beverage2 = new Soy(beverage2);
System.out.println( beverage2.getSize() + " " + beverage2.getDescription() + " $" + String.format("%.2f", beverage2.cost() ));
System.out.println("-----------------------");
Beverage beverage3 = new HouseBlend();
beverage3.setSize(Size.GRANDE);
System.out.println( beverage3.getSize() + " " + beverage3.getDescription() + " $" + String.format("%.2f", beverage3.cost() ));
beverage3 = new Soy(beverage3);
如果在装饰完对象后再次设置了Size(),则大小将正确打印为GRANDE:
beverage3.setSize(Size.GRANDE);
System.out.println( beverage3.getSize() + " " + beverage3.getDescription() + " $" + String.format("%.2f", beverage3.cost() ));
}
}
输出::
TALL House混合咖啡$ 0.89
GRANDE House混合咖啡$ 0.89
-----------------------
GRANDE House混合咖啡$ 0.89
TALL House混合咖啡,大豆$ 1.04
-----------------------
GRANDE House混合咖啡$ 0.89
GRANDE House混合咖啡,大豆$ 1.04
您的类Soy
不会覆盖getSize()
方法 - 因此,将使用基类的默认实现。 基类返回自己的size
成员,它被初始化为TALL。
为了解决这个问题,你必须在你的类Soy
相应地重写getSize()
方法:
@Override
public Size getSize() {
return this.beverage.getSize();
}
这将正确返回装饰对象的大小。
你的装饰模式的实现在概念上是不正确的。 您遇到的问题来自不正确的实施。
我在下面提到这篇维基百科文章中的5个条目:https://en.wikipedia.org/wiki/Decorator_pattern
Beverage
而CondimentDecorator
是装饰者 Soy
领域的Beverage beverage
,而不是将其添加到CondimentDecorator
CondimentDecorator
完成 CondimentDecorator
,默认情况下, getSize()
应该调用beverage.getSize()
。 其他领域也应该如此。 我认为你应该回到装饰者模式试图实现的基础知识上,并且用正确的想法来重建你的实现。 您可能能够以更简单的方式解决您的问题,但是您可能对装饰模式的实际内容有错误的想法。
请牢记以下主要观点:
如果您想要“原始”饮料的价值,我认为您必须将getSize()
委托给包装/装饰实例。
Beverage cappuccino = new Cappuccino(Size.VENTI);
Beverage soyMilkCappuccino = new Soy(cappuccino);
Soy
class Soy extends Beverage {
private final Beverage decorated;
Soy(Beverage other) { this.decorated = other; }
// delegation
Size getSize() { return decorated.getSize(); }
}
链接地址: http://www.djcxy.com/p/32007.html
上一篇: Variable resets to default value when I decorate object