JavaScript Design Pattern – Singleton Pattern

The singleton pattern is a design pattern which restricts the creation of an object to the same instance. In practical terms this means the variable defined below would be looking at the same object instance:

var object1 = new Car(),
object2 = new Car();

object2.colour = 'red';

The example above changes the colour property of object2. With the singleton pattern object1 is the same object, thus, the colour property of object1 also reflects the change. The pattern is useful when there is a need to coordinate the logic across decoupled and thus distinctly separate areas of code while maintaining access to a shared and consistent central object. Let’s look at an implementation of a singleton pattern:

function Game() {
    
    // the cached instance 
    var instance;
    
    // rewrite the constructor
    Game = function Game() {
        return instance;
    };

    // carry over the prototype 
    Game.prototype = this;

    // store the instance 
    instance = new Game();

    // reset constructor pointer 
    instance.constructor = Game;

    // default properties
    instance.lives = 3;
    instance.score = 0;

    return instance;
}

This code above creates an object called “Game”. To make sure the object is a singleton the constructor is rewritten during the object’s first invocation. This rewrite means any subsequent instances of the object simply returns the value of the instance variable. The instance variable within the object is set during the initial creation of the object prior to the new constructor being applied. Two properties are created after the line that rewrites the constructor; to repeat the above for clarity, this property creation will only be performed once for the first object.

Proving the above we can create two instances of the Game object and assert they are equal:


// update prototype and create instance
Game.prototype.player = "Greg";
var g = new Game();

// update prototype and create instance
Game.prototype.difficulty = 'hurt me plenty';

var g2 = new Game();

console.log("New player property works: " + (g.player === g2.player));
console.log("Both instances of Game are equal: " + (g === g2)); // true 
console.log("All prototype properties work: " + 
            (undefined !== 
                 (g.player && g.difficulty && g2.player && g2.difficulty)));
console.log("The initial score property works: " + g.score);
g2.score += 100;
console.log("The properties work after update: " + g.score);
console.log("The constructor points correctly: " + (g.constructor === Game));

The code above creates two instance of the Game object variables: ‘g’ and ‘g2’. The lines which follow then compare the two objects to assert the are truly equal. This will return the following result:

New player property works: true
Both instances of Game are equal: true
All prototype properties work: true
The initial score property works: 0
The properties work after update: 100
The constructor points correctly: true 

The implementation of the pattern is fairly simple. Although, the pattern does endure a fair amount of criticism. This is because the pattern implements a global space into your code which could be argued as being an anti-pattern. In my opinion used sparingly the pattern can be useful.

Advertisements

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