Java 装饰者模式:混凝土构件的字段值是构件的字段值,但为什么?
我正在玩弄《头优先设计模式》一书中的装饰模式示例。我认为Java 装饰者模式:混凝土构件的字段值是构件的字段值,但为什么?,java,decorator,Java,Decorator,我正在玩弄《头优先设计模式》一书中的装饰模式示例。我认为beverage3字段描述的值必须是“House Blend Coffee”,但它是“Unknown Beverage” 有人能解释一下吗?我们是根据接口编码的(在这个例子中,它是一个抽象类),但我仍然在实例化类HouseBlund,所以值应该是“HouseBludeCoffee”,但它不是 下面的代码并不包含示例的所有类 public class StarbuzzCoffee { public static void main(Stri
beverage3
字段描述的值必须是“House Blend Coffee”,但它是“Unknown Beverage”
有人能解释一下吗?我们是根据接口编码的(在这个例子中,它是一个抽象类),但我仍然在实例化类HouseBlund,所以值应该是“HouseBludeCoffee”,但它不是
下面的代码并不包含示例的所有类
public class StarbuzzCoffee {
public static void main(String[] args) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription()
+ " $" + beverage.cost());
Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription()
+ " $" + beverage2.cost());
Beverage beverage3 = new HouseBlend();
System.out.println("(added by me)return value of getDescription() without condiment: " + beverage3.getDescription());
beverage3 = new Soy(beverage3);
beverage3 = new Mocha(beverage3);
beverage3 = new Whip(beverage3);
System.out.println(beverage3.getDescription()
+ " $" + beverage3.cost());
System.out.println("(added by me)value of field desciption: " + beverage3.description);
}
}
饮料.java
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
调味品装饰器.java
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
public class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
@Override
public double cost() {
return beverage.cost() + .20;
}
}
java
public class HouseBlend extends Beverage{
public HouseBlend() {
description = "House Blend Coffee";
}
@Override
public double cost() {
return .89;
}
}
调味品装饰器.java
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
public class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
@Override
public double cost() {
return beverage.cost() + .20;
}
}
问题是,您正在创建的摩卡对象本身就是一种有描述的饮料。你没有改变它的描述。您正在传递另一种饮料并增强对装饰对象的描述。但是,你仍然有你以前对摩卡咖啡的描述。当您直接访问它的描述时(这就是您不使用getDescription方法所做的),您正在访问未更改的字段,因此您将打印“未知饮料” 您创建的每种饮料都有其字段描述。如果你使用它而不改变它,你会得到“未知饮料” 使类Beverage的字符串描述受保护,并且仅通过Beverage实现的重写getDescription方法访问它。请查看:
public class StarbuzzCoffee {
public static void main(String[] args) {
Beverage beverage3 = new HouseBlend();
System.out
.println("(added by me)return value of getDescription() without condiment: " + beverage3.getDescription());
beverage3 = new Mocha(beverage3);
System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
System.out.println("(added by me)value of field desciption: " + beverage3.getDescription());
}
}
abstract class Beverage {
protected String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
class HouseBlend extends Beverage{
public HouseBlend() {
description = "House Blend Coffee";
}
@Override
public double cost() {
return .89;
}
}
class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
@Override
public double cost() {
return beverage.cost() + .20;
}
}
关于设计,将饮料的getDescription抽象化并强制每个实现覆盖它会更安全。这样你将来就可以避免这种问题了。请查看:
public class StarbuzzCoffee {
public static void main(String[] args) {
Beverage beverage3 = new HouseBlend();
System.out
.println("(added by me)return value of getDescription() without condiment: " + beverage3.getDescription());
beverage3 = new Mocha(beverage3);
System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
System.out.println("(added by me)value of field desciption: " + beverage3.description);
}
}
abstract class Beverage {
protected String description = "Unknown Beverage";
public abstract String getDescription();
public abstract double cost();
}
abstract class CondimentDecorator extends Beverage {
// You don't need this code here. Because Beverage already
// provides a getDescription
// public abstract String getDescription();
}
class HouseBlend extends Beverage{
public HouseBlend() {
description = "House Blend Coffee";
}
@Override
public String getDescription() {
return description;
}
@Override
public double cost() {
return .89;
}
}
class Mocha extends CondimentDecorator{
// Also make sure that this guy here is private
// so other objects can't change or access
// its state without going through Mocha
private Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
@Override
public double cost() {
return beverage.cost() + .20;
}
}
我在答案中添加了更多的解释以帮助您。如果你还有疑问,尽管问。我以前被这个问题困扰过。。。干杯