Monday, May 29, 2006

Decorator Pattern

An example to demonstrate the Decorator design pattern which I had contributed to Wikipedia a few months back. It has since been improved and changed over there but thought maybe I should maintain a copy... Read the latest version from here.

This Java example uses the Window/Scrolling scenario

class Window {

public void draw() {
// Draw window
}
public void setSize(int height, int width) {
// Set window size
}

// Other Window methods
}
The decorator is given the same interface as the component it decorates. The decorator must be explicitly mentioned as supporting the Window interface for it to be useful in a real scenario; it must have the same type.

Typically, the decorator's methods will only pass requests to the underlying decorated component, but it can also perform operations before and after the call. Then the decorator defines extra methods (decorations) to extend the decorated component's functionality.

class VerticalScroller extends Window {

private Window myWindow;

public VerticalScroller (Window baseWindow){
myWindow = baseWindow; // Save the reference, which we will use
}

public void draw() {
//draw the vertical scroller
myWindow.draw();
}

public void setSize(int height, int width) {
//implement vertical scroller-specific functionality
myWindow.setSize(height, width);
}
}

class HorizontalScroller extends Window {

private Window myWindow;

public HorizontalScroller (Window baseWindow){
myWindow = baseWindow; // Save the reference, which we will use
}

public void draw() {
//draw the horizontal scroller
myWindow.draw();
}

public void setSize(int height, int width) {
//implement horizontal scroller-specific functionality
myWindow.setSize(height, width);
}
}

Using the decorator:

We can add a VerticalScroller decorator to a Window, say, theWindow, by saying

theWindow = new VerticalScroller (theWindow);
//A vertical scroller gets added to theWindow
//Constructor internally saves a reference to the old undecorated theWindow

The object, theWindow, will have vertical scrolling functionality after this.

No comments: