DEV Community

Daniel Breen
Daniel Breen

Posted on • Originally published at dev.to

Design Pattern Anatomy - Singleton Pattern

Introduction

The Singleton pattern restricts the instantiation of a class to a single
instance and provides a global point of access to it. It is useful when exactly
one object is needed to coordinate actions across the system.

Example

The example below demonstrates a simple implementation of the singleton pattern
to create a counter.

class Counter {
  private static instance: Counter;
  private _count: number;

  private constructor() {
    this._count = 0; // Initialize the count to 0 to prevent errors when incrementing
  }

  public static getInstance(): Counter {
    if (!Counter.instance) {
      Counter.instance = new Counter();
    }
    return Counter.instance;
  }

  public increment(): void {
    this._count++;
  }

  public getCount(): number {
    return this._count;
  }
}
Enter fullscreen mode Exit fullscreen mode

Anatomy Breakdown

Private Static Variable

A private static variable that holds the single instance of the class.

private static instance: Counter;
Enter fullscreen mode Exit fullscreen mode

Private Constructor

A private constructor to prevent direct instantiation of the class from outside.

private constructor() {
    this._count = 0; // Initialize the count to 0 to prevent errors when incrementing
}
Enter fullscreen mode Exit fullscreen mode

Public Static Access Method

A public static method (often named getInstance()) that returns the single
instance of the class, creating it if it doesn't already exist.

public static getInstance(): Counter {
    if (!Counter.instance) {
        Counter.instance = new Counter();
    }
    return Counter.instance;
}
Enter fullscreen mode Exit fullscreen mode

Usage

const counter1 = Counter.getInstance();
counter1.increment();
counter1.increment();

const counter2 = Counter.getInstance();
counter2.increment();
counter2.increment();

console.log(counter1.getCount()); // Output: 4
console.log(counter2.getCount()); // Output: 4
Enter fullscreen mode Exit fullscreen mode

Notice how both counter1 and counter2 reference the same instance, so
incrementing one affects the other. Both counter1.getCount() and
counter2.getCount() return the same value.

Top comments (0)