When is it necessary to use the decorator pattern? If possible, give me a real world example that is well-suited for the pattern.
From Gang of Four:
A graphical user interface toolkit, for example, should let you add properties like borders or behaviors like scrolling to any user interface component.
...
The decorator conforms to the interface of the component it decorates so that its presence is transparent to the component's clients. The decorator forwards requests to the component and may perform additional actions (such as drawing a border) before or after forwarding. Transparency lets you nest decorators recursively, thereby allowing an unlimited number of added responsibilities.
The intent of Decorator pattern is to:
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. [via Head First: Design Patterns]
The most heavy use of decorator pattern are GUIs and java.io classes. There is a free chapter of Head First: Design Patterns about decorator pattern [link] which provide some other examples:
We’ll re-examine the typical overuse of inheritance and you’ll learn how to decorate your classes at runtime using a form of object composition. Why? Once you know the techniques of decorating, you’ll be able to give your (or someone else’s) objects new responsibilities without making any code changes to the underlying classes.
You can also read Decorator Pattern by Example [PDF] in which decorator pattern is used in an evaluation application.
The Streams in Java - subclasses of InputStream
and OutputStream
are perfect examples of the decorator pattern.
As an example, writing a file to disk:
File toWriteTo = new File("C:\\temp\\tempFile.txt");
OutputStream outputStream = new FileOutputStream(toWriteTo);
outputStream.write("Sample text".getBytes());
Then should you require some extra functionality regarding the writing to disk:
File toWriteTo = new File("C:\\temp\\tempFile.txt");
OutputStream outputStream =
new GZIPOutputStream(new FileOutputStream(toWriteTo));
outputStream.write("Sample text".getBytes());
By simply "chaining" the constructors, you can create quite powerful ways of writing to disk. The beauty in this way is that you can add different (in this example) OutputStream
implementations later on. Also, each implementation doesn't know how the others work - they all just work to the same contract. This also makes testing each implementation very easy in isolation.
Head First Design Patterns has some more "real world" examples. It seems that O'Reilly has their sample chapter, which is on Decorator Pattern, for free; Google showed up this link: PDF
One of the coolest - and most literal - uses I've seen was to implement undo-ability, back in the bad old days of single-level undo. Given a vector drawing program, with several objects selected, of varying colors: implement a command to change all of their colors. And make it undo-able. This was done by applying a Decorator, which got invoked in the getColor() stream, so that when they were drawn, they got drawn in the new color; essentially the objects' own getColor() methods were overruled. So they showed up in the new color. To undo was as simple as removing the Decorator from all the objects; committing the action was a matter of applying the color from the Decorator to the objects and then removing it. Much simpler than keeping a table of which objects had been colored and what their original colors had been.
If you are familiar with Swing development in Java (along with other GUI toolkits), you'll see the decorator pattern used a lot. You might have a constructor that takes in a specific component and then adds functionality to it.
Here is a good article that uses Swing as an example.
When is it necessary to use the decorator pattern?
Use Decorator_pattern if
If possible, give me a real world example that is well-suited for the pattern.
I have come up with my own Vending Machine Decorator.
Problem statement: Compute the price of Beverage (Tea or Coffee) by adding one or more flavours like Sugar, Lemon etc.
Code example and explanation is available @
When to Use the Decorator Pattern?