Singleton

Ensure a class has only one instance and provide a global point of access to it.



Usage in JavaScript:
high


Summary


The Singleton Pattern limits the number of instances of a particular object to just one. This single instance is called the singleton.

Singletons are useful in situations where system-wide actions need to be coordinated from a single central place. An example is a database connection pool. The pool manages the creation, destruction, and lifetime of all database connections for the entire application ensuring that no connections are 'lost'.

Singletons reduce the need for global variables which is particularly important in JavaScript because it limits namespace pollution and associated risk of name collisions. The Module pattern (described in the Modern Patterns section) is JavaScript's manifestation of the Singleton pattern.

Several other patterns, such as, Factory, Prototype, and Façade are frequently implemented as Singletons when only one instance is needed.


Diagram



Participants


The objects participating in this pattern are:

  • Singleton -- In sample code: Singleton
    • defines getInstance() which returns the unique instance.
    • responsible for creating and managing the instance object.

JavaScript Code


The Singleton object is implemented as an immediate anonymous function. The function executes immediately by wrapping it in brackets followed by two additional brackets. It is called anonymous because it doesn't have a name.

The getInstance method is Singleton's gatekeeper. It returns the one and only instance of the object while maintaining a private reference to it which is not accessible to the outside world.

The getInstance method demonstates another design pattern called Lazy Load. Lazy Load checks if an instance has already been created; if not, it creates one and stores it for future reference. All subsequent calls will receive the stored instance. Lazy loading is a CPU and memory saving technique by creating objects only when absolutely necessary.

Singleton is a manifestation of a common JavaScript pattern: the Module pattern. Module is the basis to all popular JavaScript libraries and frameworks (jQuery, Backbone, Ember, etc.). The Module and Lazy Load patterns are discussed in the Modern Patterns section.


var Singleton = (function () {

    var instance;

    function createInstance() {
        var object = new Object("I am the instance");
        return object;
    }

    return {
        getInstance: function () {
            if (!instance) {
                instance = createInstance();
            }

            return instance;
        }
    };
})();


function run() {

    var instance1 = Singleton.getInstance();
    var instance2 = Singleton.getInstance();

    alert("Same instance? " + (instance1 === instance2));  
}
Run



JavaScript Optimized Code


The Namespace pattern is applied to keep the code out of the global namespace. Our namespace is named Patterns.Classic. A Revealing Module named Singleton encapsulates all of Singleton's functions and variables. It exposes just one method named getInstance. This method will return the one and only instance if it already exists; if not it will create a new instance and save it off in a private local variable for all subsequent calls.

The Patterns object contains the namespace function which constructs namespaces non-destructively, that is, if a name already exists it won't overwrite it.

The log function is a helper which collects and displays results.


var Patterns = {
    namespace: function (name) {
        var parts = name.split(".");
        var ns = this;

        for (var i = 0, len = parts.length; i < len; i++) {
            ns[parts[i]] = ns[parts[i]] || {};
            ns = ns[parts[i]];
        }

        return ns;
    }
};

Patterns.namespace("Classic").Singleton = (function () {

    var instance;

    var createInstance = function () {
        return {
            say: function () {
                alert("I am the greatest");
            }
        };
    }
        
    var getInstance = function () {
        return instance = instance || createInstance();
    }

    return {
        getInstance: getInstance
    };

})();


function run() {

    var singleton = Patterns.Classic.Singleton;

    var instance1 = singleton.getInstance();
    var instance2 = singleton.getInstance();

    instance1.say();                        // => I am the greatest!

    alert("Same instance? " + (instance1 === instance2)); // => true
}
Run



  Prototype
Adapter