Decorator : Design Pattern

Overview

Design Patterns are a reusable solutions to a commonly seen software desgin problem. The key item to remember is that these patterns are more like templates and instructions and are not reusable code. Although helpful and can solve many problems they are not usefull in every case and can hinder you from finding the best solution if you get in the mentality of  “what pattern should I use for x”. The better mentality is “does this functionality fit any patterns?”.

Decorator

The Decorator design pattern put simply is a way to add dynamic functionality to an object. This pattern is an alternative to sub-classing.  The basic pattern is that instead of sub-classing a base object to modify its values you create a decorator object that wraps the object and performs any modifications to functions that need changing or calls the base object functions.

The easiest way to explain this pattern is with an example. And what could be better then ice-cream.

Example

Lets start with a base object of an ice cream. In this example we will be modifing one value cost.

class IceCream {
    public IceCream() {}

    public getCost(){
        return 1.00;
    }
}

Next we will define the various modifications we can make to the ice cream as Decorators, For example we could add Sprinkles, Hot Fudge, and Cherry Dip. The basics elements to the decorator is that it takes an object into its constructor that it “decorates” or modifies.

class Sprinkles {
    private _baseObj;

    public Sprinkles( baseObj ) {
        this._baseObj = baseObj;
    }

    public function getCost() {
        return this._baseObj.getCost() + .25;
    }
}
class HotFudge{
    private _baseObj;

    public HotFudge( baseObj ) {
        this._baseObj = baseObj;
    }

    public function getCost() {
        return this._baseObj.getCost() + .50;
    }
}
class CherryDip{
    private _baseObj;

    public CherryDip( baseObj ) {
        this._baseObj = baseObj;
    }

    public function getCost() {
        return this._baseObj.getCost() + .50;
    }
}

You may have noticed that defining an interface that all decorators and base object implement is a great idea, but for the purpose of the demo we don’t need to. Now that the decorators are defined we can now modify or “decorate” our ice cream

var myIceCream = new HotFudge( new Sprinkle(new IceCream()) );
myIceCream.getCost();

The Cost of my icream will be 1.75 as seen this pattern is an excellent way to implement modifications to objects without creating distinct subclasses and allows the program to use whichever decorators it requires at run time by simply wrapping the base object.  Further details as well as non pseudo code examples can be found at wikipedia

Comments & Questions

Add Your Comment