首先设计模式 - 装饰模式描述/成本

时间:2013-03-31 01:22:41

标签: design-patterns decorator

我是OO Design Patterns的新手,对Java来说相对较新。

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

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

例如:

这是Mocha类(装饰):

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();
}

}

这是Beverage类(基础):

public abstract class Beverage {

String description = "Unknown Beverage";

public String getDescription()
{

    return description;
}

public abstract double cost();

}

Dark Roast Class:

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

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

2 个答案:

答案 0 :(得分:3)

如果您不重复使用名称,这将有所帮助。假设您已将代码编写为:

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

变量mocha是Mocha,mocha.beverage == roast,是DarkRoast。

变量doubleMocha是Mocha,doubleMocha.beverage == 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中大量使用。一个在BufferedInputReaders中包装InputReaders,然后可能在更奇特的类中包装。
  2. 切勿将floatdouble s用于货币值。您是否曾见过适用的天真代码的结果,对您的2.99美元商品征收4.5%的税,并将其报告为3.12455美元?也很容易错误地解决问题。
  3. 如果你能找到一本二手Java版本的旧版本,Felleisen,Friedman和Johnson的一些模特,那就买吧。它对这类代码有很好的描述。

    顺便说一下,只使用一个变量名的原始代码有效,因为首先将变量设置为DarkRoast对象。然后,例程创建一个使用Mocha对象的DarkRoast对象,一旦将实例变量设置为Mocha对象,原始DarkRoast仍然可以很强地访问。垃圾收集器不会丢弃它。

答案 1 :(得分:1)

描述是用

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

请注意,Mocha的说明会调用Beverage类的说明。

费用按

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

因此,Mocha类的成本会将Beverage类的成本作为其计算的一部分。