Decorator Pattern in JavaScript – GoF Design Patterns

23Jun08

Since moving into the new office we’ve been trying really hard to set things up in such a way that a culture of learning and knowledge sharing is created. In addition to pair programming, a reading area and an ever growing library, we’ve set aside three hours of group study time a week. As with all things under Scrum, the time, duration, date, topic and existence of the study periods was voted on by the development teams. We settled on three sessions a week – Tuesday: GoF Design Patterns, Wednesday: Open Mic(anybody can present anything) and Thursday: JavaScript.

Miika and I are leading the design pattern session and I’m leading the JavaScript session. So what is the obvious progression from this……?

Well I’m guessing you’ve already read the title so I doubt I’ve built up much suspense – Design Patterns in JavaScript!

We are using Head First Design Patterns as our study guide as it is much easier to digest than any of the other books are, especially for people who speak English as a second language. So the plan is to post each one of the examples from the book implemented in JavaScript, I’m then going to post those example to Wikipedia as JavaScript is currently not very well represented in most of the design pattern entries.

I’m not the first person to cover the subject, in fact Ross Harmes, Dustin Diaz have already written an excellent book on the subject, but I am going to take a slightly different angle. The plan is to where ever possible avoid building constructs that try to imitate the constructs of other languages, so I will be avoiding using helper methods to mimic interfaces, abstract classes and other constructs and instead embrace JavaScript’s dynamic nature.

Here’s the pizza example from the Head First book in JavaScript:

//Class to be decorated
function Coffee(){
    this.cost = function(){
        return 1;
    };
}

//Decorator A
function Milk(coffee){
    this.cost = function(){
        return coffee.cost() + 0.5;
    };
}

//Decorator B
function Whip(coffee){
    this.cost = function(){
        return coffee.cost() + 0.7;
    };
}

//Decorator C
function Sprinkles(coffee){
    this.cost = function(){
        return coffee.cost() + 0.2;
    };
}

//Here's one way of using it
var coffee = new Milk(new Whip(new Sprinkles(new Coffee())));
alert( coffee.cost() );

//Here's another
var coffee = new Coffee();
coffee = new Sprinkles(coffee);
coffee = new Whip(coffee);
coffee = new Milk(coffee);
alert(coffee.cost());

As you can see by the procedural code using the decorator pattern in JavaScript is much the same as its usage in other more orthodox languages, the big difference is in the implementation of the pattern. As you can see there is no defined interface. JavaScript has no Interface construct, the answer to this as with many other dynamic languages is duck typing (Note: Wikipedia needs a JavaScript duck typing example).

Duck Typing shifts the responsibility of making sure an object meets an interface from the creator to the receiver. Which is exactly what is happening above, the decorators receive an object which needs to implement the coffee interface by having a single method named cost(). If the object passed in does not have a method called coffee, then an exception will be raised by the JavaScript interpreter at runtime.

I guess what I’m trying to say is the main thing for me when addressing design patterns is that the ‘what’ (behaviour) is more important than the ‘how’ (implementation). In JavaScript the how is duck typing, in Java the how is an interface, but who cares? The important part is the what, and in both if we try to utilize an object which doesn’t meet our interface then an exception will be raised.

Advertisements


One Response to “Decorator Pattern in JavaScript – GoF Design Patterns”

  1. 1 mmiika

    Saw a different, more verbose way as well: http://peter.michaux.ca/article/7965


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: