装饰模式混乱?

Decorator Pattern Confusion?

我一直在研究装饰器模式,在理解它的其中一个问题时有点困惑。我一直在读 "decorators are typically transparent to the client of the component; that is, unless the client is relying on the component's concrete type"。我不确定这意味着什么——例如,如果我们有饮料 class 和咖啡子 class,这是否意味着客户依赖咖啡,所以如果它被装饰,会有是不是有些问题?

是的。 如果您依赖于实现而不是抽象(抽象 类 或接口),那对于想要在两者之间添加装饰器的 someone/you 来说将是一个严重的问题。

请参考Solid Principles的依赖倒置原理。
这是其核心的一般规则:

one should “Depend upon Abstractions. Do not depend upon concretions“

考虑代码:

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

这里MochaWhipCoffee是具体的类,Beverage是抽象的。现在你的装饰很好,因为客户端最终取决于 Beverage (抽象类型)。

现在考虑具有如下代码的客户:

if (beverage instanceof Mocha) {
    <do_something>
}
else if (beverage instanceof Coffee ) {
    <do_something>
}

这里有问题,因为客户端对不同的具体类型有特定的行为。

因为我们想要依赖抽象而不是具体类型,所以我们在像 Spring 这样的流行框架中使用依赖注入的概念(代码依赖于抽象类型)。您可以在 martin Fowler 的 article 中阅读有关 IOCDI 的更多信息。

我希望它能解释“装饰器通常对组件的客户端是透明的;也就是说,除非客户端依赖于组件的具体类型

旁注 instanceof 是一个糟糕的设计,它没有充分利用 OO,应该避免。