Singleton pattern

"Ensures a class only has one instance, and provide a global point of access to it."

Use when

  • Exactly one instance of a class is required.
  • Controlled access to a single object is necessary.

The Problem

Well designed systems pass object instances around via method calls (see Dependency Injection). Each class retains its independence from the wider context, collaborating with other parts of the system via clear lines of communication. Sometimes this forces you to use some classes as conduits for objects that do not concern them, introducing dependencies in the name of good design.

Imagine an User class that holds application-level information. We might use a User object to store data such as Id, Name, Preferences, Purchases history, and so on.

Passing an User object around from object to object may not always be a good idea. Many classes that do not otherwise use the object could be forced to accept it simply so that they could pass it on to the objects that they work with. This is just another kind of coupling.

You also need to be sure that all objects in your system are working with the same User object. You do not want objects setting values on one object, while others read from an entirely different one.

Let’s distill the forces in this problem:

  • An User object should be available to any object in your system.
  • An User object should not be stored in a global variable, which can be overwritten.
  • There should be no more than one User object in play in the system. This means that object A can set a property in the User object, and object B can retrieve the same property, without either one talking to the other directly (assuming both have access to the User object).

Things to consider before using

They are generally used as a global instance, why is that so bad? Because you hide the dependencies of your application in your code, instead of exposing them through the interfaces. Making something global to avoid passing it around is a code smell.

They violate the single responsibility principle: by virtue of the fact that they control their own creation and lifecycle.

They inherently cause code to be tightly coupled. This makes faking them out under test rather difficult in many cases.

They carry state around for the lifetime of the application. Another hit to testing since you can end up with a situation where tests need to be ordered which is a big no no for unit tests. Why? Because each unit test should be independent from the other.

The "static member function accessor" approach will not support subclassing of the Singleton class.

Deleting a Singleton class/instance is a non-trivial design problem.

Examples

A static method cannot access object properties because it is, by definition, invoked in a class and not in an object context. It can, however, access a static property. When getInstance() is called, the User::$instance property is checked. If it is empty, then an instance of the User class is created and stored it in the property. Then the instance is returned to the calling code. Because the static getInstance() method is part of the User class, there is no problem instantiating a User object even though the constructor is private.


public class User {

    private User() {
        // Private constructor prevents instantiation from other classes
    }

    /**
     * Singleton is loaded on the first execution of User.getInstance()
     * or the first access to Singleton.INSTANCE, not before.
     */
    private static class Singleton {
        private static final Singleton INSTANCE = new User();
    }

    public static User getInstance() {
        return Singleton.INSTANCE;
    }
}


public class User {

    protected static $instance = null;

    private function __construct() {
        // Private constructor prevents instantiation from other classes
    }

    public static function getInstance() {
        if (static::$instance === null) {
            static::$instance = new self();
        }
        return static::$instance;
    }
}


// Singleton with a closure
function User() {

    var instance;

    // rewrite the constructor
    User = function() {
        return instance;
    };

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

    instance = new User();

    // reset the constructor pointer
    instance.constructor = User;

    return instance;
}


import Foundation

private let _instance = SingletonObject()

class SingletonObject {

    static let sharedInstance = SingletonObject()

    private init() {
    }
}

Can be accessed with


SingletonObject.getInstance

By defining its constructor as private we prevent instantiation from other classes and forces them to call it statically with User::getInstance()

Other patterns

Abstract Factory
Adapter
Bridge
Builder
Chain of Responsibility
Command
Composite
Decorator
Factory Method
Facade
Flyweight
Prototype
Interpreter
Mediator
Memento
Observer
Proxy
State
Strategy
Template Method
Visitor