July 7th, 2008 | by matthew |
OK, so lets start off with the GOF Decorator Pattern which allows us to extend functionality at runtime, without using inheritance. The Decorator object wraps the instance whose functionality it’s enhancing, but implements the same interface as the original object. It delegates calls to the wrapped object, but has the opportunity to augment the behaviour of the method before and/or after the delegated call. Here’s a very simple example.

That’s it! A Decorator. You may have used it already without realising!
Got more than one minute? OK, lets go into a bit more detail. We may well want to implement a number of different decorators, which we can combine in different ways at runtime. (This will be much more flexible than if we’d used inheritance.) Now we can add an abstract decorator base class which can handle the wrapped instance and the delegation (which all our decorators will have in common).Let’s decorate a Christmas Tree!
The Decorators aren’t actually Christmas Trees themselves. In fact they are useless without a real tree to wrap themselves around. They impersonate a Tree by implementing the interface, but delegate all of the real work of being a tree to the wrapped instance. How about some code.
Here’s the abstract Decorator base class.
public abstract class ChristmasTreeDecorator implements ChristmasTree {
private ChristmasTree wrappedChristmasTree;
public ChristmasTreeDecorator(ChristmasTree tree) {
wrappedChristmasTree = tree;
}
protected ChristmasTree getTree() {
return wrappedChristmasTree;
}
}
There’s a great opportunity here to use another GOF pattern – Template Method, but I’ve resisted the temptation to keep things simple. If you have time, have a look yourself at how it might fit in.
Here’s the an example of a concrete Decorator class.
public class FairyDecorator extends ChristmasTreeDecorator {
public FairyDecorator(ChristmasTree tree){
super(tree);
}
public void cheerRoom() {
// could add behaviour before delegated call too if we want...
getTree().cheerRoom();
addFairy();
}
private void addFairy() {
System.out.println("Top off with a festive fairy!");
}
}
And here’s some test code.
public class DecoratorTest {
public static void main(String[] args) {
System.out.println("Here's my new tree, let's see how it cheers the room...");
ChristmasTree tree = new NorwaySpruce();
tree.cheerRoom();
System.out.println("\nA bit dull, lets add some lights...");
tree = new LightsDecorator(tree);
tree.cheerRoom();
System.out.println("\nNot bad, how about some tinsel...");
tree = new TinselDecorator(tree);
tree.cheerRoom();
System.out.println("\nAnd now the finishing touch, a fairy...");
tree = new FairyDecorator(tree);
tree.cheerRoom();
}
}
Notice how Decorators can be nested. A good example of this pattern in the Java APIs is the I/O Stream classes.




Sorry, comments for this entry are closed at this time.