Decorator模式和委托模式之间的区别

时间:2012-11-15 00:02:53

标签: java design-patterns decorator delegation

Decorator模式和委托模式之间有什么区别(如果有的话)?我不想知道实现细节,还要了解用例差异和主观观点如何使用它们。

  

编辑:您是否可以指向源代码(在OS项目中),其中使用了这些模式(尤其是Delegation,因为在Java IO类中使用了Decoration)。我正在寻找一些真正的用法而不只是虚拟的例子。也许这些模式只是在标题上有所不同。随意写下这个意见。

2 个答案:

答案 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类中没有更改代码,并且该类的用户对缓存一无所知。