1

While going through Decorator Pattern from Wikipedia 1 and reading pattern from Head First Book . One thing that struck me and is missing from both the sources or i may have missed it.

Why exactly do we need a Decorator Interface ?

  • Is it because we need to put all the Concrete Decorators under categorical umbrella.

Suppose if we had only few ( <5) Decorators , Cant we simply sublcass them directly from Component Interface. Terms from wikipedia UML Thus Decorator will be storing the reference of Component Interface Type and it will call the behaviour directly of the Concrete Component after doing adding some more to it. This is the same thing as per the examples from the Head First Book.

Another reason that i can think of Putting a Decorator Interface is to have Runtime support for Adding those Decorators through Factory. This is the only reason that i can make of.

Asking here to wider audience, Is Decorater Interface in Decorator Design Pattern is just for providing Dynamic Support via Factory or there is more to it.

  • 1
    How would you chain decorators then? – Telastyn May 26 '18 at 20:23
  • Wouldnt that will happen from Component Interface. As decorator will be inherited that. – ATul Singh May 26 '18 at 20:26
  • 1
    Oh, yes. That is what I thought you had meant. Looking at the wiki again, I see what you mean, I’ve never found that interface to be of any value. – Telastyn May 26 '18 at 20:55
  • From the first diagram (the simplest black-and-white UML diagram which is the first one on the Wikipedia article), the only property that exists on the box named "Decorator" (presumably the abstract, non-empty base class for all decorators) is the property named "component" (a reference to the underlying component being wrapped or "decorated"). There seems nothing else. So, if there is not a need to "tag" (distinguish) decorators (e.g. there is no intention to give external access to that reference to that wrapped component), then the box that's named "Decorator" isn't necessary. – rwong May 27 '18 at 9:18
2

The main reason that I can see for the Decorator interface/base class in the Decorator pattern is the make it clear in the pattern description what the common characteristics are of the ConcreteDecorators.

This means that, in my view, there do not have to be distinct classes that correspond to Decorator and ConcreteDecorator when using the Decorator pattern, especially if there are only a few decorators. When there are many, it can be helpful to have a separate class for the common behavior to reduce the amount of code duplication.

1

The main two reasons in my opinion are:

  • Making semantically clear what's a decorator and what's not.
  • Isolating the core component from the decorators by providing an extension point. You could design your base application/framework with just the decorator interface, and let other decorators be added via plug-ins.

In addition to that, you can do all kind of interesting stuff like picking all the decorators an instance can use with reflection.

In many patterns the abstract interface can be omitted, but you should be very confident that it will not be needed later. It's a good idea to leave them there in general. They're a very useful way to isolate components and change.

0

You can do things that you can't with inheritance:

  1. You can decorate sealed/final classes.
  2. You can remove or change the access modifier of any member not in the interface.
  3. You can make non-virtual methods virtual.
  4. You can remove inheritable attributes.

So for example if you were building a code library in c# that had a very powerful object, you could do this:

public interface IGod 
{
    void CreateAllLife();
}

public IBasic
{
    void DoSomethingMundane();
}

internal sealed class GodObject : IBasic, IGod
{
    public void CreateAllLife() { Console.WriteLine("Let there be light"); }
    public void DoSomethingMundane() { Console.WriteLine("Burrrp."); }
}

public class Decorator : IBasic
{
    private GodObject _god;

    public virtual void DoSomethingMundane() => _god.DoSomethingMundane();
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.