Intent

  • Ensures that a class can be instantiated only once and enables a global access point to that instant

Implementation

  • Make the class constructor private
  • Use a static method to return the instance
    • On the very first call the static method will call the constructor
class Singleton {
    private static instance: Singleton;
 
	private constructor() { }
    
    public static getInstance(): Singleton {
        if (!Singleton.instance) {
            Singleton.instance = new Singleton();
        }
        return Singleton.instance;
    }
 
    public someBusinessLogic() {
        // ...
    }
}
 
function clientCode() {
    const s1 = Singleton.getInstance();
    const s2 = Singleton.getInstance();
 
    if (s1 === s2) {
        console.log('Singleton works, both variables are the same instance.');
    } else {
        console.log('Singleton failed, variables are different instances.');
    }
}
 
clientCode();
public final class Singleton {
    private static Singleton instance;
    public String value;
 
    private Singleton(String value) {
        // The following code emulates slow initialization.
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        this.value = value;
    }
 
    public static Singleton getInstance(String value) {
        if (instance == null) {
            instance = new Singleton(value);
        }
        return instance;
    }
}
 
public class DemoSingleThread {
    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance("FOO");
        Singleton anotherSingleton = Singleton.getInstance("BAR");
 
		System.out.println(singleton.value);
        System.out.println(anotherSingleton.value);
    }
}
 
// Output
 
// FOO
// FOO
 

Examples

  • Many printers but one printer spool
  • one window-manager instance for an OS
  • one file-logger instance to prevent concurrency issues

Pros

  • The object is initialized only on the first call

Cons

  • Violates Single responsibility principle
  • Unit testing is harder as we need an innovative way to test the class having a private constructor

Nton

  • N instances of a class
  • Use a static counter and an instance array
  • Make sure it’s thread safe
  • Helpful with load balancing