Open main menu

CDOT Wiki β

Decorator

Revision as of 18:58, 21 February 2007 by Dtolj (talk | contribs)

Allow new/additional responsibility to be added to an existing object dynamically. Decoratores provide a flexible alternative to subclassing for extending functionality.

UML Class diagram of the decorator pattern

Introduction

  • structual pattern
  • aka Wrapper
  • allows us to add things to a component without requiring every subclass to inherit these new qualities.
  • Function added at runtime through composition.
  • We want an object to do something new, not its class

Motivation

Sample Code

window/scrolling scenario

// the Window interface
interface Window {
   public void draw(); // draws the Window
   public String getDescription(); // returns a description of the Window
}

// implementation of a simple Window without any scrollbars
class SimpleWindow implements Window {
   public void draw() {
       // draw window
   }

   public String getDescription() {
       return "simple window";
   }
}

The decorator classes

// abstract decorator class - note that it implements Window
abstract class WindowDecorator implements Window {
   protected Window decoratedWindow; // the Window being decorated

   public WindowDecorator (Window decoratedWindow) {
       this.decoratedWindow = decoratedWindow;
   }
}

// the first concrete decorator which adds vertical scrollbar functionality
class VerticalScrollBarDecorator extends WindowDecorator {
   public VerticalScrollBarDecorator (Window decoratedWindow) {
       super(decoratedWindow);
   }

   public void draw() {
       drawVerticalScrollBar();
       decoratedWindow.draw();
   }

   private void drawVerticalScrollBar() {
       // draw the vertical scrollbar
   }

   public String getDescription() {
       return decoratedWindow.getDescription() + ", including vertical scrollbars";
   }
} 

// the second concrete decorator which adds horizontal scrollbar functionality
class HorizontalScrollBarDecorator extends WindowDecorator {
   public HorizontalScrollBarDecorator (Window decoratedWindow) {
       super(decoratedWindow);
   }

   public void draw() {
       drawHorizontalScrollBar();
       decoratedWindow.draw();
   }

   private void drawHorizontalScrollBar() {
       // draw the horizontal scrollbar
   }

   public String getDescription() {
       return decoratedWindow.getDescription() + ", including horizontal scrollbars";
   }
}

main program

public class DecoratedWindowTest {
   public static void main(String[] args) {
       // create a decorated Window with horizontal and vertical scrollbars
       Window decoratedWindow = new HorizontalScrollBarDecorator (
               new VerticalScrollBarDecorator(new SimpleWindow()));

       // print the Window's description
       System.out.println(decoratedWindow.getDescription());
   }
}

Example

  • Decorating our Beverages
  • Java I/O

References

Gamma, Erich; Helm, Richard; Johnson, Ralph; Vlissides, John (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley. ISBN 0-201-63361-2. http://www.dofactory.com/Patterns/PatternDecorator.aspx