Design Patterns w/ AS3 Part 2: Decorator Pattern
The decorator pattern takes the concept of composition over inheritance a step further. In this pattern, we will attach additional responsibilities to an object to extend its functionality. Inheritance is used in this pattern for type matching, but not for applying behavior to an object. The behavior comes from the concrete components we will create as well as any decorators we will use on the object, and because this behavior does not come through inheritance we will not have to modify existing code to add new behavior. We simply add an additional decorator for the behavior(s) we want to add.
This is a place where we want to follow the Open-Closed Principle — Classes should be open for extension, but closed for modification. So in this example, we have a coffee shop that currently sells 4 types of coffee, with 4 types of condiments that can be added to each coffee. We *could* do this through inheritance, but any changes will result in making modifications to our parent class. For example, if new condiments are added or prices are changed it will force us to make changes to the code and potentially introduce new bugs. Also, beverages added at a later time may inherit certain condiments that do not apply (or taste very good either).
So to start, we are going to build our own coffee shop. First we start with the main class, the Beverage class:
public class Beverage { public var description:String = "Unknown Beverage"; public function getDescription():String { return description; } public function cost():Number { return 0; } }
Now we create our condiment decorator, that needs to match the type of our beverage class:
public class CondimentDecorator extends Beverage { override public function getDescription():String { return ''; } }
Now for the coffee. We’ll start with an Espresso component that will extend the Beverage class:
public class Espresso extends Beverage { public function Espresso():void { description = "Espresso"; } override public function cost():Number { return 1.99; } }
And Finally, we’ll create our first decorator:
public class Whip extends CondimentDecorator { public var beverage:Beverage; public function Whip(beverage:Beverage) { this.beverage = beverage; } override public function getDescription():String { return beverage.getDescription() + ", Whip"; } override public function cost():Number { return 0.10 + beverage.cost(); } }
Now that we have our decorators and components set up, we can quickly and easily create a coffee and determine its price:
var beverage:Beverage = new Espresso(); beverage = new Whip(beverage); trace('You ordered:' + beverage.getDescription() + ' $' + beverage.cost());
Here is a demo of everything compiled together, you can view the source as well.
19 May 2009 0 comments

In this scenario, you would have to override your quack method to make the duck squeak, and override the fly method to do nothing. Since these things change and we are following the Strategy Pattern, we must pull these methods out of the Duck class and separate them. This is where we bring in our friend, the Interface. Programming to an interface allows us to avoid a concrete implementation of behavior from our Duck superclass and allows for a set of classes that are strictly used for behaviors. First, we create an interface for Flying Behavior:

