Web Development

Decorator Pattern in JavaScript

By Stoyan Stefanov, November 29, 2011

Dynamically add functionality to JavaScript objects at runtime

Decorator is a Gang-of-Four design pattern that allows additional functionality to be added to an object dynamically, at run time. When dealing with static classes, this could be a challenge. In JavaScript, objects are mutable, so the process of adding functionality to an object is not a problem.

A convenient feature of the decorator pattern is the customization and configuration of the expected behavior. You start with your plain object, which has some basic functionality. Then you pick and choose from an available pool of decorators which ones you want to use to enhance your plain object and in which order, if the order is important.

Usage

Say you're working on a Web application that sells something. Every new sale is a new sale object. The sale "knows" about the price of the item and can return it by calling the sale.getPrice() method. Depending on the circumstances, you can start decorating this object with extra functionality.

Imagine a scenario where the sale for a customer is in the Canadian province of Quebec. In this case, the buyer needs to pay a federal tax and a provincial Quebec tax. Following the decorator pattern, you'll say that you "decorate" the object with a federal tax decorator and a Quebec tax decorator. You can then also decorate the object with price-formatting functionality. This scenario could look like the following:

As you can see, this is a flexible way to add functionality and tweak an object at run time. Let's see how to approach an implementation of the pattern.

Implementation

One way to implement the decorator pattern is to have each decorator be an object containing the methods that should be overwritten. Each decorator actually inherits the object enhanced so far after the previous decorator. Each decorated method calls the same method on the uber (the inherited object), gets the value, and proceeds with doing something in addition.

The end effect is that when you do sale.getPrice() in the first example, you're calling the method of the money decorator, as shown in Figure 1. But because each decorated method first calls the parent's method, money's getPrice() first calls quebec's getPrice()/, which in turn calls fedtax's getPrice(), and so on. The chain goes all the way up to the original undecorated getPrice() implemented by the Sale() constructor.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!