【问题标题】:Decorator design pattern issue?装饰器设计模式问题?
【发布时间】:2012-09-28 06:01:43
【问题描述】:

'Head first design patterns'一书的装饰器章节中,谈到了装饰器处理具体类型并引发问题的问题。我正在复制章节中的一些问答:

问:我有点担心代码可能会测试特定的具体组件(比如 HouseBlend)并做一些事情,比如发布折扣。一旦我用装饰器包裹了 HouseBlend,这将不再起作用。

A:完全正确。如果您的代码依赖于具体组件的类型,装饰器将破坏该代码。只要您只针对抽象组件类型编写代码,装饰器的使用对您的代码将保持透明。但是,一旦您开始针对具体组件编写代码,您将需要重新考虑您的应用程序设计和装饰器的使用。

有人可以举一些简单的例子来说明“客户端”代码是针对具体类型还是抽象类型编写的?前者是如何给装饰者带来麻烦的?

书中一个装饰器的示例测试代码是这样的:

public class StarbuzzCoffee {
    public static void main(String args[]) {
        Beverage beverage2 = new DarkRoast();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription()
            + “ $” + beverage2.cost());
        ...
    }
}

这个测试代码(也是客户端代码)是针对抽象类型编写的吗?

谢谢,

【问题讨论】:

    标签: oop design-patterns decorator


    【解决方案1】:

    他们在谈论检查饮料类型的代码,例如

    if (beverage2 instanceof DarkRoast) {
        <do_something>
    }
    

    一旦你用摩卡或鞭子装饰饮料2,它就不再是 DarkRoast。

    编辑:我还应该提到,instanceof 的使用通常表明一个糟糕的设计,没有充分利用 OO,这表明它在某些情况下很有用。

    【讨论】:

      【解决方案2】:

      只要您只针对抽象组件类型编写代码,装饰器的使用对您的代码将保持透明

      是的。这就是它应该的方式。

      您不应装饰特定于具体装饰器实现的新功能。一旦你这样做了,装饰器模式的目的就失去了。

      装饰器模式运行良好,因为抽象装饰器包含接口本身(使用组合)。它有助于减少不同口味的不同组合的数量。

      我已经为类似的用例实现了Decorator 模式。看看这个文档链接

      When to Use the Decorator Pattern?

       Beverage beverage = new SugarDecorator(new LemonDecorator(new Tea("Assam Tea")));
       beverage.buildBeverage();
      

      您将得到 18 的输出,这是 Tea (10) + Lemon (5) + Sugar (3) 的总和:

      Cost of:Assam Tea+Lemon +Sugar :18
      

      要使上述示例生效,您需要对摘要 Decorator 进行一些更改,如文档链接中所述。由于BeverageDecorator 抽象类中的组合,可以轻松添加多种风味。

      永远不要添加基于 Concrete Decorator 的业务逻辑。如果你在代码中加入了 Concrete Decorator 的智能,你就会失去独立添加动态职责的灵活性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-05
        • 1970-01-01
        • 2020-05-13
        • 2016-10-05
        • 1970-01-01
        • 1970-01-01
        • 2013-11-28
        相关资源
        最近更新 更多