Decorator Pattern

Intent: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

While reading the GangOfFour book on CD I noticed that the original name of this pattern was "Wrapper". -- DaveMitchell

See also: CompositePattern, ProxyPattern, DesignPatterns

This pattern was also called shadowing in LPC.



This pattern can also be used as a way to refactor a complex class into smaller pieces. Even if you don't need to attach responsibilities dynamically it can be clearer to have each responsibility in a different class. Somewhat like MixIns. -- ChristianTaubman

Also see AspectOrientedProgramming
The "Adapter" pattern is also known as "Wrapper" pattern (WrapperPattern). Is Wrapper/Adapter/Decorator the same pattern?

No. AdapterPattern is used to convert the interface of an object into something else. DecoratorPattern is used to extend the functionality of an object while maintaining its interface. Both of these are probably sometimes called WrapperPattern since both of them do "wrap" an object.


My understanding is that the DecoratorPattern does not refer to just any dynamic modifications to a class. My understanding is that it works like this:

This is very different from what I've heard people say "the Decorator Pattern" means - I've heard people saying that pretty much anything that dynamically changes a class is an instance of "the Decorator Pattern."

So for instance, if you dynamically change a class at run-time in a language that lets you do that, you are now using, "The Decorator Pattern." If there's a feature of a language that lets you add a method to a class at run-time, they're calling that use of "the decorator pattern."

Reality check?


The description above implies that decorating an object changes its behaviour but not its interface. Is that necessarily true? For example, say you have a spell-check dictionary object. You want to get statistics on the most commonly misspelled words, so you wrap your spell-check dictionary in an envelope that tracks statistics. It exposes new methods for reading the stats.

Now it's true that the original client of the spell-check dictionary is in no way aware of the expanded interface. So from its perspective, your modification has not changed the interface. Isn't this an example of the DecoratorPattern?


In python, the 'random' module has a shuffle function which shuffles a list: random.shuffle(lyst) but what you mean is lyst.shuffle(); so importing the random module should add the shuffling behaviour to lists. Is this the DecoratorPattern?


An example of this pattern is how java.io's Readers and Writers work.


The difference that I see between a DecoratorPattern and subclassing is that you can decorate any class that implements an interface with a single class. Say I wanted to give myself a java.util.Map that printed a message whenever I added or removed a key. If I only ever actually used java.util.HashMap I could just create PrintingMap? as a subclass of HashMap and override put & remove. But if I want to create a printing version of TreeMap then I either create PrintingTreeMap? (which has almost identical code to PrintingMap? (which should itself become PrintingHashMap?)), or I create a Map decorator.

In short, you are trading "have to write pass-throughs for every method, not just the ones you're changing & do 2 step object creation", for "have to write a subclass for each concrete class you want to change". This goes from helpful to imperative if you are writing a library for others to use.

In java jdk 1.3 added dynamic proxy

that is a great way to "decorate" any object

author has added pre-method / post-method processing, which is decorating the instance

http://www.ibm.com/developerworks/java/library/j-jtp08305.html


The term "wrapper" its used for several software design patterns, so an alternative, more specific identifier, should be used.

The Decorator Design Pattern has several requirements.

(1) An object that requires the extension.

Example:

A window control that requires additional optional features like:

An example with an Object Oriented C style pseudocode:

  public class WindowClass?
  {
    // ...
  } // class

(2) Several objects that support the extension by "decoration". Usually, those objects share a common interface, traits, or superclass, and sometimes, additional, intermediate superclasses .

  /* abstract */ public class WindowDecoratorClass?
  {
    // ...
  } // class

/* concrete*/ public class WindowTitleBarClass?: extends WindowDecoratorClass? { // ... } // class

/* concrete*/ public class WindowStatusBarClass?: extends WindowDecoratorClass? { // ... } // class

/* abstract */ public class WindowScrollbarClass?: extends WindowDecoratorClass? { // ... } // class

/* concrete*/ public class WindowHorizontalScrollbarClass?: extends WindowScrollbarClass? { // ... } // class

/* concrete*/ public class WindowVerticalScrollbarClass?: extends WindowScrollbarClass? { // ... } // class

(3) The decorated object (class or prototype instantation), and the decorator objects have one or several common features. In order to enssure that functuonality, the decorated object & the decorators have a common interface, traits, or class inheritance.

In the next example, the "Draw();" method & the "GetDescription?();" method are the features that are the requirement, and are defined by the "DrawingControlInterface?",

  public interface WindowDecoratorInterface?
  {
    // ...

public String GetDescription?() { ... }

public void Draw() { ... }

// ... } // interface

public class WindowClass?: implements WindowDecoratorInterface? { public String GetDescription?() { ... }

public void Draw() { ... } } // class

/* abstract */ public class WindowDecoratorClass?: implements WindowDecoratorInterface? { public String GetDescription?() { ... }

public void Draw() { ... } } // class

/* concrete*/ public class WindowTitleBarClass?: extends WindowDecoratorClass? { public String GetDescription?() { ... }

public void Draw() { ... } } // class

/* concrete*/ public class WindowStatusBarClass?: extends WindowDecoratorClass? { public String GetDescription?() { ... }

public void Draw() { ... } } // class

/* abstract */ public class WindowScrollbarClass?: extends WindowDecoratorClass? { public String GetDescription?() { ... }

public void Draw() { ... } } // class

/* concrete*/ public class WindowHorizontalScrollbarClass?: extends WindowScrollbarClass? { public String GetDescription?() { ... }

public void Draw() { ... } } // class

/* concrete*/ public class WindowVerticalScrollbarClass?: extends WindowScrollbarClass? { public String GetDescription?() { ... }

public void Draw() { ... } } // class


CategoryPattern | CategoryStructuralPatterns

EditText of this page (last edited February 14, 2013) or FindPage with title or text search