Decorator模式和委托模式之间有什么区别(如果有的话)?我不想知道实现细节,还要了解用例差异和主观观点如何使用它们。
编辑:您是否可以指向源代码(在OS项目中),其中使用了这些模式(尤其是Delegation,因为在Java IO类中使用了Decoration)。我正在寻找一些真正的用法而不只是虚拟的例子。也许这些模式只是在标题上有所不同。随意写下这个意见。
答案 0 :(得分:26)
Decorator使用Delegation,但是以非常具体的方式。
委托(或组合)不是通过协调使用其他几个对象来构建复杂行为的一般方式。它通常以集合或静态方式使用。通过“设置或静态”我的意思是这样的:
class Delegator {
private final ClassA a = new ClassA();
private final ClassB b = new ClassB();
public void doWork() {
a.setup();
final ResFromA resa = a.getRes();
b.setup();
b.consume(resa);
}
}
请注意,Delegator不与ClassA或ClassB共享任何类型或接口,并且知道a和b的确切类型。
Decorator是一种使用委托在运行时向逻辑实体添加行为的动态方法。在Decorator中,所有实体共享一个公共接口,并使用委托来连接它们的工作。
public interface Item {
public void drawAt(final int x, final int y);
}
public class CircleAround implements Item {
private final Item wrapped;
private final int radius;
public CircleAround(public final Item wrapped, public final int radius) {
this.wrapped = wrapped;
this.radius = radius;
}
public void drawAt(final int x, final int y) {
// First handle whatever we are wrapping
wrapped.drawAt(x,y);
// Then add our circle
Graphics.drawCircle(x, y, radius);
}
}
请注意,与第一个示例不同,CircleAround不知道它包装的项目的确切类型,并与它共享一个公共接口。
答案 1 :(得分:5)
我认为'委托模式'会很难清楚地判断什么是或不是模式的试金石。例如,人们仍然总是说'我知道工厂模式'。没有工厂模式。这是一个成语(参见James Coplien的高级C ++)。该页面也相当薄弱;我认为简单的授权不是责任倒置。
当要装饰的代码必须增强时,使用装饰器。装饰器将自己包裹在decoratee周围并仍然调用它的方法,它只是在之前或之后完成。这是当Aspects出现时你看到人们谈论装饰器的原因之一:它是一种依赖于中介而不是合作的模式。 (这也是为什么在许多情况下,例如当你没有源时,你必须使用装饰器。)
当你想要采取一些有效的东西并让它做其他事情时,装饰师效果最好,但根本不改变界面。想象一下,你有一个Repository类,它会输出一个包含CRUD方法的接口。现在您要添加缓存。您可以创建一个装饰Repository的CachedRepository,在读取时,它会在缓存中查找,如果它不存在,那么它将调用常规存储库方法,否则,它只能返回缓存的副本。在Repository类中没有更改代码,并且该类的用户对缓存一无所知。