抽象装饰器类中的功能而不是装饰器

我目前正在阅读“Head First Design Patterns”一书,并在Decorator章节中有以下示例:

示例图

在本书中,CondimentDecorator类被描述为abstract decorator 。 这里是代码示例:

public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

所以基本上,里面只是一个抽象的方法,它强制所有的子类重写Beverage类中的getDescription()方法。

这里是作为decorator者的Mocha类的代码示例。

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

除硬编码成本号(.20)和名称(“,Mocha”)外,其他装饰器(Whip类,Soy类...)具有完全相同的代码。

然后我们通过将前一个对象传递给新的装饰器来使用这个装饰器模式。

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

现在对于我创建的每个新的装饰器,我都必须通过构造函数为超类构造函数提供前一个饮料对象,并且需要覆盖只返回特定装饰器唯一值的方法。

这段代码好吗? 或者,如果我在抽象装饰器中有功能,它是否完全改变了Decorator模式的要点?


这段代码很好。 教科书通常(?)在他们的例子中提供了不完美的代码,因此他们可以专注于一个特定的概念(在这种情况下是装饰器)并且不会引起对其他细节的关注。 事实上,你找到了一种改进本书代码的方法,这表明你实际上理解了这个概念,足以智能地使用它,而不仅仅是从引用中复制粘贴。


我认为答案是你不想在一个班上做两件事。

CondimentDecorator做一件事:连接两种饮料。 它真的应该被命名为“MixDecorator”

当您将编码调味品的常见方面分解出来时,您需要创建另一个类,可称为“NamedPricedCondiment”,并将名称和成本放在那里。

链接地址: http://www.djcxy.com/p/32009.html

上一篇: Functionality inside abstract decorator class instead of decorators

下一篇: Variable resets to default value when I decorate object