Singleton

Intent

Singleton is a creational design pattern that lets you ensure that a class has only one instance and provide a global access point to this instance.

Problem

Singleton solves two problems at the time (violating Single Responsibility Principle):

  1. Ensures that a class has only a single instance. The most common reason for this is to control some shared resource, for example, database.

    Imagine that you had created an object, and after a while, tried to create a new one. In this case, you would want to receive the old object, instead of creating a new instance.

    It can not be done with a regular constructor since every constructor call always returns a new object by design.

  2. Provides global access point to that instance. Sound like a global variable, right? But you can not make a read-only global variable. Anyone who can access it can also replace its value.

    There is another side of this problem: you do not want the code which solves the previous problem to be scattered all over your program. It is much better to have it within one class, especially if rest of your code already depends on that class.

Note that Singleton solves both of these problems at the same time. But nowadays pattern became so popular that people call something a Singleton even if it solves just one of these problems.

Solution

All singleton implementations share two common steps:

  • Making the default constructor private.
  • Creating a static creation method that will act as a constructor. This method creates an object using the private constructor and saves it in static variable or field. All following calls to this method return the cached object.

Singleton keeps the single instance production code in one place—inside the creation method of a Singleton class. Any client code that has access to Singleton class gets the access to its creation method as well. And that gives us a global access point to the Singleton instance.

Real-World Analogy

Government

The government is an excellent example of Singleton pattern. A country can have only one official government. Regardless of the personal identities of the individuals who form governments, the title, "The Government of X" is a global point of access that identifies the group of people in charge.

Structure

Singleton design pattern
  1. Singleton declares static method getInstance() that should return the same instance of Singleton class.

    Singleton's constructor should be hidden from client code. getInstance() should be the only way to create and get Singleton objects.

Pseudocode

In this example, the database connection class acts as a Singleton. This class does not have a public constructor, so the only way to get its object is to call the getInstance method. This method caches the first created object and returns it as a result of all subsequent calls.

The Single design pattern guarantees that the only one instance of its class will be created. And it provides a global access point to this instance: the static getInstance method.

class Database is
    private field instance: Database

    static method getInstance() is
        if (this.instance == null) then
            acquireThreadLock() and then
                // Ensure that instance has not yet been initialized by other
                // thread while this one has been waiting for the lock release.
                if (this.instance == null) then
                    this.instance = new Database()
        return this.instance

    private constructor Database() is
        // Some initialization code, such as the actual connection to a
        // database server.
        // ...

    public method query(sql) is
        // All database queries of an app will go through this methods.
        // Therefore, you can place a throttling or caching logic here.
        // ...

class Application is
    method main() is
        Database foo = Database.getInstance()
        foo.query("SELECT ...")
        // ...
        Database bar = Database.getInstance()
        bar.query("SELECT ...")
        // The variable `bar` will contain the same object as the variable `foo`.

Applicability

When program should have a single instance of a class, available to all clients. For example, a single database object, shared by different parts of the program.

Singleton hides from clients all means of creating new objects of its class, except the special creation method. This method either creates a new object or returns existing object if it had been created before.

When you need a stricter control over global variables.

Unlike global variables, Singleton guarantees that there is just one class' instance. No one, except Singleton itself, can replace the cached instance.

Moreover, Singleton lets you easily change this restriction. For example, to allow any number of instances, you will only need to alter the code in one place—inside getInstance() body.

How to Implement

  1. Add to the class a private static field that will hold the singleton instance.

  2. Declare public static creation method that will be used for retrieving singleton instance.

  3. Implement "lazy initialization" inside the creation method. It should create a new instance on the first call and put it into the static field. The method should return that instance in all subsequent calls.

  4. Make class constructor private.

  5. In client code replace all direct constructor calls with calls to the static creation method.

Pros and Cons

  • Ensures that class has only a single instance.
  • Provides global access point to that instance.
  • Allows deferred initialization.
  • Violates Single Responsibility Principle.
  • Masks bad design.
  • Requires special treatment in a multithreaded environment.
  • Requires endless mocking in unit tests.

Relations with Other Patterns

  • Facade can be transformed into Singleton since most of the time single facade object is sufficient.

  • Flyweight looks almost like Singleton in cases where it's possible to reduce everything to just one flyweight object. But remember, there are two fundamental differences between these patterns:

    1. Singleton object can be mutable. Flyweight objects are immutable.
    2. There should be only one Singleton instance, whereas Flyweight class can have multiple instances with a different intrinsic state.
  • Abstract Factory, Builder and Prototype can be implemented as Singletons.

Implementations in Different Programming Languages

Java