Back to Overview

Singleton Pattern

The Singleton Pattern is a creational design pattern that ensures a class has only one instance while providing a global point of access to that instance. It's useful when exactly one object is needed to coordinate actions across the system.

Problem

There are cases when we need to ensure that a class has just a single instance:

The regular constructor call always creates a new object, so we need a mechanism to ensure only one instance exists and provide global access to it.

Singleton Class Private Constructor Static Instance Field GetInstance Method Client A Client B Client C GetInstance() GetInstance() GetInstance() All clients get the same instance

Components

Implementation Example

Here's a basic implementation of the Singleton pattern in JavaScript:

class Singleton {
    // Private static instance - holds the single instance
    static #instance = null;
    
    // Some state to demonstrate the singleton maintains state
    #counter = 0;
    
    // Private constructor - prevents direct instantiation
    constructor() {
        // Check if an instance already exists
        if (Singleton.#instance) {
            throw new Error("Cannot create multiple instances of Singleton. Use getInstance() instead.");
        }
    }
    
    // Public static method to get the singleton instance
    static getInstance() {
        // Create the instance if it doesn't exist yet
        if (!Singleton.#instance) {
            Singleton.#instance = new Singleton();
            console.log("Singleton instance created");
        }
        
        return Singleton.#instance;
    }
    
    // Example of instance methods that maintain state
    incrementCounter() {
        return ++this.#counter;
    }
    
    getCounter() {
        return this.#counter;
    }
}

Usage Example

// This is how clients use the singleton
function clientCode() {
    // Get the singleton instance
    const singleton1 = Singleton.getInstance();
    console.log(`Counter value: ${singleton1.getCounter()}`);
    
    // Increment the counter
    singleton1.incrementCounter();
    console.log(`After increment: ${singleton1.getCounter()}`);
    
    // Get the singleton instance again - it's the same instance
    const singleton2 = Singleton.getInstance();
    console.log(`Second reference counter: ${singleton2.getCounter()}`);
    
    // They are the same object
    console.log(`Are they the same instance? ${singleton1 === singleton2}`);
}

// Run the client code
clientCode();

Interactive Demo: Logger Singleton

This demo demonstrates a Logger implemented as a Singleton. All clients get the same instance, allowing for centralized logging.

Instance 1: Not created yet
Instance 2: Not created yet
Log Count: 0

When to Use

Benefits

Considerations

Real-World Uses