Skip to content
Creational

Singleton

Ensure a class has only one instance and provide a global point of access to it.

Intent

Restrict the instantiation of a class to a single object and provide a well-known access point for that instance, ensuring coordinated access to a shared resource.

Problem

Multiple parts of your application need access to the same shared resource — such as a configuration store, connection pool, or logging service — but creating multiple instances would cause conflicts, duplicated state, or wasted resources. There is no built-in language mechanism to guarantee a single instance while still allowing lazy initialization.

Solution

Make the default constructor private and provide a static creation method that acts as the constructor. On the first call it creates the instance and caches it; on subsequent calls it returns the cached instance. Thread safety must be considered in concurrent environments.

Participants

  • Singleton — the class that manages its own unique instance and provides a static accessor
  • Client — any code that obtains the instance through the static accessor rather than direct construction

Advantages

  • Guarantees that only one instance of the class exists throughout the application lifetime
  • Provides a global access point to that instance without relying on global variables
  • The instance is created only when first requested, enabling lazy initialization

Disadvantages

  • Violates the Single Responsibility Principle by coupling instance management with business logic
  • Can mask bad design by hiding dependencies instead of making them explicit via constructor injection
  • Makes unit testing difficult because the global state persists between tests
  • Requires special handling in multi-threaded environments to avoid race conditions during initialization

Real-World Analogy

A country has exactly one 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 in charge. You don't create a new government each time someone needs to interact with it — you access the existing one.

Use Cases

  • Database connection pool shared across an application
  • Application-wide configuration or settings registry
  • Centralized logging service
  • Hardware interface access such as a printer spooler
  • Caching layer that must be consistent across modules

Code Examples

Thread-safe singleton using a private constructor and a static getInstance method with lazy initialization. TypeScript's module system naturally runs once, so the class-based approach is mainly useful when you need controlled, deferred creation.