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

mic*_*man 19 java design-patterns delegation decorator

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

编辑:你能指出使用这些模式(特别是Delegation,因为在Java IO类中使用装饰)的源代码(在OS项目中).我正在寻找一些真正的用法而不只是虚拟的例子.也许这些模式只是在标题上有所不同.随意写下这个意见.

And*_*sen 27

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

}
Run Code Online (Sandbox Code Playgroud)

请注意,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);
  }

}
Run Code Online (Sandbox Code Playgroud)

请注意,与第一个示例不同,CircleAround不知道它包装的项目的确切类型,并与它共享一个公共接口.

  • 装饰器是委派的子集,但定义非常明确。装饰器用于通过一次添加一个特征来构造一个复杂的对象。使用的机制是委托。所以从这个意义上讲,是的,它们是同一回事。但是,一个代表团比另一个更为广泛。在我看来,它们不是一回事。您可能还声称,所有模式“实际上只是多态性和组成”。是的,它们使用这些机制来构建,但它们不只是它们各个部分的总和。 (2认同)

Rob*_*Rob 6

我认为“委派模式”会很明显地使石制测试失败。例如,人们总是一直说“我知道工厂模式”。没有工厂模式。这是一个习惯用法(请参阅James Coplien的Advanced C ++)。该页面也很薄弱。我不认为简单的委派是责任的倒置。

当必须修饰的代码必须增加时使用装饰器。装饰器将自己包装在被修饰对象周围,并且仍然调用其方法,它只是在之前或之后执行操作。这是当Aspects出现时,您会看到很多人都在谈论Decorator的原因之一:这是一种依赖中介而不是合作的模式。(这也是为什么在许多情况下(例如,当您没有源时,必须使用Decorator的原因。)

当您想使用正在运行的功能并让其执行其他操作,而根本不更改界面时,Decorator的工作效果最佳。想象一下,您有一个Repository类,其中包含一个包含CRUD方法的接口。现在,您要添加缓存。您可以创建一个CachedRepository来装饰存储库,并在读取时在缓存中查找,如果不存在,则将调用常规存储库方法,否则,它可以仅返回缓存的副本。Repository类中没有更改任何代码,并且该类的用户对缓存一无所知。