Difference between Decorator pattern and Delegation pattern
Asked Answered
C

2

32

What is the difference between Decorator pattern and Delegation pattern (if there is any) ? I don't want to know just about implementation details but also about use case differencies and subjective point of view how to use them.

EDIT : Can you point to source code (in OS project) where these pattern (especially Delegation, because Decoration is used in Java IO classes) are used. I'm looking for some real usage not just dummy example. Maybe these patterns are the same differs only in title. Feel free to write this opinion.

Convert answered 15/11, 2012 at 0:2 Comment(0)
T
36

Decorator uses Delegation, but in a very specific way.

Delegation (or composition) is not as much a pattern as a general way to build complex behavior by coordinating use of several other objects. It's often used in a set or static way. By "set or static" I mean something like this:

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

}

Note that Delegator does not share any type or interface with either ClassA or ClassB, and knows the exact type of both a and b.

Decorator is a dynamic way to use delegation to add behavior to a logical entity at runtime. In Decorator all entities share a common interface, and use delegation to concatenate their work.

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

}

Note that unlike the first example, CircleAround does not know the exact type of the item that it wraps, and shares a common interface with it.

Threlkeld answered 15/11, 2012 at 8:17 Comment(2)
Hi, thanks for your answer. In wiki page I've posted here is an example of complex Delegation where author sharing common interface of delegate. I looking for difference in usage of these two approaches (not just implementation) from client side. Maybe (as I found on many places around internet) it's the same with just different title.Convert
Decorator is a subset of delegation, but a very well defined one. Decorator is used to construct a complex object by adding features one at a time. The mechanism used is delegation. So in that sense, yes they are the same thing. But one - delegation - is much broader than the other. To my mind they are NOT the same thing. You might as well claim that all patterns are "really just polymorphism and composition". Yes, they are BUILD using these mechanisms, but they are more than the sum of their parts.Threlkeld
E
10

I think that 'Delegation Pattern' would fail the litmus test of what is or is not a pattern pretty clearly. For example, people still say 'I know the Factory Pattern' all the time. There is no Factory pattern. That's an idiom (cf. Advanced C++ by James Coplien). That page is pretty weak too; I don't see simple delegation as an inversion of responsibility.

Decorator is used when the code being decorated must be augmented. The Decorator wraps itself around the decoratee and still calls its methods, it just does stuff before or after. This is one of the reasons you see people talking about Decorator quite a lot when Aspects come up: it's a pattern that relies on intermediation, not cooperation, with its cohort. (This is also why in many cases, e.g. when you don't have the source, you must use a Decorator.)

Decorator works best when you want to take something that's working and have it do something else, but not change the interface at all. Imagine you have a Repository class that puts out an interface that has CRUD methods in it. Now you want to add caching. You can make a CachedRepository that decorates Repository and on read, it looks in the cache, if it's not there, then it would call the regular repository method, otherwise, it can just return the cached copy. No code was changed in the Repository class and the users of the class know nothing about the caching.

Eustasius answered 15/11, 2012 at 0:20 Comment(5)
Hi, thanks for your answer. I think I understand Decorator quite well as you described here. I agree with you. But you wrote about Delegation less clearly. Can you point me to some better article about Decorator? I tried it and there are a lot of pages where it seems people calling Delegation and show Decoration and vice versa. I'm quite confused about it.Convert
+1 for "Delegation Pattern would fail the litmus test of what is or is not a pattern pretty clearly". It did not come up to my mind.Convert
To me delegation is, as I said, not a pattern. It's simply a way of saying one thing will employ another to get something done. There are responsibility implications of that and there are opportunities for making things more abstract through such interfaces. Coplien would describe delegation as an idiom. I'm not even sure I'd go that far. I would say it's basically just a plug point for some discreet division of labor. If you want to read a good discussion of the idea, there is none better than Coplien's in Advanced C++. He refers to it as Envelope/Letter.Eustasius
@Rob: Don't you think that depends on the way the pattern/idiom is used in a particular language. For e.g: In Objective-C the delegation pattern is used quite often as a design itself and not as a way to 'take something that is working and have it do something else'.Cuomo
You misunderstand what I was saying. I am saying that the Delegate Pattern is not really a pattern, and it's for sure not a Decorator. I am saying the Delegate Pattern is NOT a Decorator.Eustasius

© 2022 - 2024 — McMap. All rights reserved.