2

我对 OO 设计模式很陌生,对 Java 也比较陌生。

我的问题是关于 Head First Designer Patterns Starbuzz 示例中的装饰器示例。

我无法理解外部包装器如何调用内部包装器,特别是这些示例中的描述如何连接起来。

例如:

这是摩卡类(装饰):

public class Mocha extends CondimentsDecorator {

Beverage beverage;

public Mocha(Beverage beverage) {

    this.beverage = beverage;
}

public String getDescription()
{
    return beverage.getDescription() + " , Mocha";
}

public double cost()
{
    return .20 +  beverage.cost();
}

}

这是饮料类(基础):

public abstract class Beverage {

String description = "Unknown Beverage";

public String getDescription()
{

    return description;
}

public abstract double cost();

}

黑烤类:

public class DarkRoast extends Beverage {

public DarkRoast() {
    description = "Dark Roast";
}

@Override
public double cost() {

    return .99;
}

}

所以,如果我运行这个:

 Beverage beverage2 = new DarkRoast();
 beverage2 = new Mocha(beverage2);
 beverage2 = new Mocha(beverage2);

 System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

输出是:

Dark Roast , Mocha , Mocha $1.39

我不明白描述是如何构建的并将成本加在一起?描述和成本的状态如何保持?我在这里遗漏了一些明显的东西吗?

4

2 回答 2

5

如果您不重复使用名称,它将有所帮助。

有意义的名称示例

假设您将代码编写为:

Beverage roast = new DarkRoast();
mocha = new Mocha(roast);
doubleMocha = new Mocha(mocha);
System.out.println(doubleMocha.getDescription() + " $" + doubleMocha.cost());

变量mocha是 Mocha 和mocha.beverage == roastDarkRoast。

变量doubleMocha是 Mocha,并且doubleMocha.beverage == mocha是 Mocha。

请注意doubleMocha.beverage.beverage == roast. 成本也可以在整个链条上进行委派:

dobleMocha.cost() == .20 + doubleMocha.beverage.cost() 
                  == .20 + mocha.cost() 
                  == .20 + .20 + mocha.beverage.cost()
                  == .20 + .20 + roast.cost()
                  == .20 + .20 + 1.99 = 2.39

你可以doubleMocha.description()用同样的方法想办法。

其他问题

随着你的进步,你会学到更多的东西。

  1. 装饰器在 Java IO 中被大量使用。一种将 InputReaders 包装在 BufferedInputReaders 中,然后可能包装在更奇特的类中。
  2. 切勿使用floats 或doubles 表示货币值。你有没有见过对你的 2.99 美元商品征收 4.5% 税并将其报告为 3.12455 美元的幼稚代码的结果?错误地四舍五入也很容易。

阅读更多

如果您能找到以下书籍的二手副本,请购买:

它对这种类型的代码有很好的描述。

垃圾收集器保留引用

顺便说一句,仅使用一个变量名的原始代码是有效的,因为首先将变量设置为一个DarkRoast对象。然后例程创建一个Mocha使用该对象的DarkRoast对象,并且一旦将实例变量设置为该Mocha对象,原来DarkRoast的仍然是强可达的。垃圾收集器不会处理它。

于 2013-03-31T01:47:02.930 回答
1

描述是用

public String getDescription() 
{
    return beverage.getDescription() + " , Mocha";
}

请注意,类的描述Mocha调用了Beverage类的描述。

费用计算如下

public double cost()
{
    return .20 +  beverage.cost();
}

所以Mocha类的成本调用类的成本Beverage作为其计算的一部分。

于 2013-03-31T01:32:21.720 回答