The Decorator Pattern

The decorator pattern is one of the classic structural patterns. A decorator wraps an existing object and provides additional functionality (decoration) whilst providing the same interface as the original object.

One example which comes to mind is from an episode of Flight of the Conchords. Bret tries to ‘upgrade’ an ordinary mobile phone by gluing a camera to it. Whilst he is initially excited by this new ‘camera phone’, he later discovers that it is quite difficult to use as some of the controls are inaccessible.

In programming terms, what Bret is trying to do is to ‘wrap’ his phone to create a new object, namely a camera phone. Where his plan falls down is his new camera phone does not expose all the functionality of the original phone.

Example – Spin control

One area in which the decorator pattern is particularly applicable is Windows controls. This is because of the flexible nature of windows. There are some basic ‘building block’ items such as text fields and buttons. Then there are more complicated controls such as the spin box which are assembled from these building blocks.

Page Setup dialog

As can be seen in the screenshot, the spin control is made up of a numeric text field and two buttons, one to increment the number and one to decrement it.

Suppose we have a NumberBox class for entering integer values. This class has a getValue() method for retrieving the integer value entered by the user.

How would we go about creating a SpinControl class? It would seem logical to have the same interface as the NumberBox to retrieve the user input. We might also have a setIncrement() function to control how the spin buttons work.

The interface for our two classes would be as follows:

SpinBox interface

Both NumberBox and SpinBox implement the same getValue() control. It would be nice if we could formalize this by having them implement the same interface. That way, any application which uses NumberBox controls will still work if we switch it to use SpinBox controls.

We also want to reuse the functionality of NumberBox rather than duplicating code inside the SpinBox class. We shall achieve this via composition rather than inheritance.

The proposed design is shown in the following UML class diagram:

UML class diagram for SpinBox class

Note that this is just a simple example for illustration. The standard decorator pattern is more flexible, but I hope this gives a useful introduction.