我已阅读有关装饰器模式的this article,我有一个问题。
此类仅来自抽象类SandWichDecorator
:
public class CheeseDecorator extends SandWichDecorator{
Sandwich currentSandwich;
public CheeseDecorator(Sandwich sw){
currentSandwich = sw;
}
@Override
public String getDescription(){
return currentSandwich.getDescription() + ", Cheese";
}
@Override
public BigDecimal price() {
return currentSandwich.price().add(new BigDecimal("0.50"));
}
}
为什么在abstract
类中引用Sandwich
类Sandwich currentSandwich;
CheeseDecorator
?
将它放入抽象类SandWichDecorator
会更容易吗?
每个扩展SandWichDecorator
的班级都会自动获得参考。
答案 0 :(得分:2)
你的建议很好恕我直言。 它也匹配GOF原件: decorator
在讨论模式时,重要的是要记住变体是可以接受的,没有"模式警察"谴责你的每一个小小的偏差(只要考虑得很好)......如果是我,我将一些文章的AbstractClasses改为接口,我仍然相信我的设计意图清晰可接受。
也许你可以在评论中询问作者(虽然它是一篇旧帖子)。如果我不得不猜测,我会假设作者想要在" currentSandwich"中保留一些灵活性。声明/位置(比如从一个threadLocal中取出它,组合两个sandwitches等),但是这样的“创造力”和#39;会破坏一般性和模块性 - 即将几个装饰者包裹在另一个上面的自由。我更喜欢我的装饰师坚持一个明确定义的" currentSandwitch",在这种情况下采用你的想法是好的。
答案 1 :(得分:2)
是的,你是对的。您可以在current
中使用SandwichDecorator
三明治,如下所示:
public abstract class SandwichDecorator implements Sandwitch {
protected final Sandwitch current;
public SandwichDecorator(Sandwitch current) {
this.current = current;
}
}
但实际上,你甚至不需要SandwichDecorator
课程。您可以拥有一个接口Sandwich
并实现它。仅仅因为持有"装饰"而不是一个抽象的课程是不值得的。参考:
interface Sandwich {
String description();
float price();
}
class BasicSandwich implements Sandwich {
@Override
public String description() {
return "Sandwich";
}
@Override
public float price() {
return 4f;
}
}
class CheeseSandwich implements Sandwich {
private final Sandwich origin;
public CheeseSandwich(Sandwich origin) {
this.origin = origin;
}
@Override
public String description() {
return origin.description() + " , Cheese";
}
@Override
public float price() {
return origin.price() + 1f;
}
}
//More implementations of Sandwich
你可以像这样使用它:
Sandwich completeSandwich = new CheeseSandwich(new BasicSandwich());
使用接口进行设计比使用抽象类更灵活。每次你写extends
时,一只小猫都会死。
答案 2 :(得分:2)
模式的本质是允许静态或动态地将新功能/改变的行为添加到对象,而不会影响同一类对象的行为。
您利用多态来实现这一目标。基本抽象类或接口提供要作为输入和输出传递的对象的“类别”以进行装饰。
这只是作者选择展示模式的方式,我同意你的看法,它可能更精简。
Hector提供的示例(没有SandwichDecorator类)在我看来更好地实现了该示例的模式。