javadesign-patternsdecoratordelegation

Difference between Decorator pattern and Delegation pattern


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.


Solution

  • 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.