装饰器模式和委派模式之间的区别

装饰器模式和委派模式(如果有的话)有什么区别?我不仅仅想知道实现细节,还想知道用例差异和如何使用它们的主观观点。

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


答案 1

装饰器使用委派,但以非常具体的方式。

委托(或组合)与其说是一种模式,不如说是通过协调使用其他几个对象来构建复杂行为的一般方法。它通常以集合或静态方式使用。通过“设置或静态”,我的意思是这样的:

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);
  }

}

请注意,委托人不与 ClassA 或 ClassB 共享任何类型或接口,并且知道 a 和 b 的确切类型。

装饰器是一种动态方式,用于在运行时使用委派向逻辑实体添加行为。在 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 不知道它包装的项的确切类型,而是与它共享一个公共接口。


答案 2

我认为“委派模式”将无法很好地测试什么是模式,什么不是模式。例如,人们仍然一直说“我知道工厂模式”。没有工厂模式。这是一个成语(参见詹姆斯·科普林(James Coplien)的高级C++)。该页面也非常弱。我不认为简单的授权是责任的颠倒。

当必须扩充要修饰的代码时,将使用修饰器。装饰器将自己包裹在被装饰者周围,并且仍然调用其方法,它只是在之前或之后做一些事情。这是你看到人们在Asspects出现时经常谈论Expercor的原因之一:这是一种依赖于中介而不是与其队列合作的模式。(这也是为什么在许多情况下,例如,当您没有源代码时,您必须使用装饰器。

装饰器在你想要获取一些有效的东西并让它做其他事情时效果最好,但根本不改变界面。假设您有一个存储库类,它提出了一个包含 CRUD 方法的接口。现在,您要添加缓存。您可以创建一个装饰存储库的缓存存储库,并且在读取时,它会在缓存中查找,如果它不存在,那么它将调用常规存储库方法,否则,它可以只返回缓存的副本。存储库类中没有更改任何代码,并且该类的用户对缓存一无所知。


推荐