我一直在对装饰模式进行一些研究,并且在理解其中一个问题时会有一些混乱。我一直在读“装饰器通常对组件的客户端是透明的;也就是说,除非客户端依赖于组件的具体类型”。我不确定这意味着什么 - 例如,如果我们有Beverage类和Coffee子类,这是否意味着客户端依赖于Coffee,所以如果它被装饰,会有一些问题吗?
答案 0 :(得分:1)
考虑代码:
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());
...
}
}
此处Mocha
,Whip
和Coffee
是具体类,Beverage
是抽象类型。现在你的装饰很好,因为客户最终取决于Beverage
(抽象类型)。
现在考虑一个客户端,代码如下:
if (beverage instanceof Mocha) {
<do_something>
}
else if (beverage instanceof Coffee ) {
<do_something>
}
这里有问题,因为客户端具有针对不同具体类型的特定行为。
由于我们希望依赖于asbtraction而不是具体类型,我们在像Spring这样的流行框架中使用依赖注入的概念(代码依赖于抽象类型)。您可以通过martin Fowler在此article中详细了解IOC
和DI
。
我希望它解释“装饰器通常对组件的客户端是透明的;也就是说,除非客户端依赖于组件的具体类型”
在旁注instanceof
是一个糟糕的设计,它不会使用OO来充分利用,应该避免使用。
答案 1 :(得分:0)
是的确切。 如果您依赖于实现而不依赖于抽象(抽象类或接口),对于想要在其间添加装饰器的人/您来说,这将是一个严重的问题。
请参阅Solid Principles的依赖性倒置原则 这是其核心的一般规则:
应该“依赖于抽象。不要依赖于结核“