【问题标题】:Functionality inside abstract decorator class instead of decorators抽象装饰器类中的功能而不是装饰器
【发布时间】: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


【解决方案1】:

这段代码很好。教科书经常(?)在他们的示例中提供不太完美的代码,因此他们可以专注于特定的概念(在这种情况下 - 装饰器)而不是引起对其他细节的注意。您找到了改进本书代码的方法这一事实表明,您实际上已经充分理解了这个概念,可以智能地使用它,而不仅仅是从参考文献中复制粘贴。

【讨论】:

    【解决方案2】:

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

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

    当您将调味品的共同方面分解为编码时,您需要创建另一个类,可以将其称为“NamedPricedCondiment”并将名称和成本放入其中。

    【讨论】:

      猜你喜欢
      • 2013-04-12
      • 2019-01-18
      • 2021-12-05
      • 1970-01-01
      • 2020-09-25
      • 2023-03-28
      • 2022-01-09
      • 2015-02-07
      • 2013-10-20
      相关资源
      最近更新 更多