【发布时间】:2017-05-13 23:17:07
【问题描述】:
我目前正在阅读本书Head First Design Patterns,在装饰器章节中有以下示例:
在书中,CondimentDecorator 类被描述为abstract decorator。下面是代码示例:
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
所以基本上里面只有一个抽象方法,它强制所有子类覆盖 Beverage 类的getDescription() 方法。
这是一个 Mocha 类的代码示例,即decorator。
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
public double cost() {
return .20 + beverage.cost();
}
}
其他装饰器(Whip 类、Soy 类...)具有完全相同的代码,除了硬编码的成本编号 (.20) 和名称 (" ,摩卡”)。
然后我们通过将前一个对象传递给新的装饰器来使用这个装饰器模式。
Beverage beverage = new DarkRoast();
beverage = new Mocha(beverage);
beverage = new Mocha(beverage);
beverage = new Whip(beverage);
我的问题是,为什么不简单地将重复的功能从装饰器转移到抽象装饰器?这是我重构示例的方式。
抽象装饰器:
public abstract class CondimentDecorator extends Beverage {
private Beverage beverage;
protected CondimentDecorator(Beverage previousBeverage) {
this.beverage = previousBeverage;
}
@Override
public String getDescription() {
return beverage.getDescription() + ", " + getAdditionName();
}
@Override
public double cost() {
return beverage.cost() + getAdditionCost();
}
public abstract String getAdditionName();
public abstract double getAdditionCost();
}
装饰器代码:
public class Mocha extends CondimentDecorator {
public Mocha(Beverage beverage) {
super(beverage);
}
@Override
public String getAdditionName() {
return "Mocha";
}
@Override
public double getAdditionCost() {
return 0.20;
}
}
现在,对于我创建的每个新装饰器,我都必须通过构造器为超类构造器提供先前的饮料对象,并且我需要覆盖仅返回特定装饰器的唯一值的方法。
这段代码可以吗?或者如果我在抽象装饰器中有功能,它会完全改变装饰器模式的意义吗?
【问题讨论】:
-
如果你改变它的实现,你实际上是在问你是否改变了装饰器模式的这种使用点。而是问 - 装饰器模式的意义何在?如果您对此有所了解,您会发现您仍然有饮料装饰器,无论是否有您的编辑。
标签: java design-patterns decorator