Catalog / Creational Patterns / Singleton Pattern
CREATIONAL

Singleton Pattern

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

Intent & Objective

Restrict the instantiation of a class to one single object throughout the application lifecycle, while providing a thread-safe, coordinated global access point.

👥 Real-World Human Analogies & Social Roles
4 Intuitive Scenarios
The Family Doctor Healthcare Coordination

"Just like you do not want multiple conflicting doctors giving you contradictory prescriptions, a Singleton ensures there is only one authoritative instance managing your medical records."

The Passport Office Legal Authority

"Only one official government authority is legally empowered to issue recognized national passports, preventing duplicate and conflicting identification."

School Principal Organizational Leadership

"A school has only one head principal overseeing operations, curriculum, and school-wide discipline."

Morning Alarm Clock Developer Daily Life

"Exactly one alarm clock instance wakes you up in the morning—no duplicates allowed to cause conflicting chaos."

The Problem

Shared hardware access (e.g., printer spooler, serial communication port), global configuration management, or connection pooling require exactly one coordinator. Creating multiple instances causes race conditions, cache desynchronization, and resource exhaustion.

The Solution

Make the constructor private, store a static reference to the unique instance, and provide a static method (e.g. `getInstance()`) that returns this instance, lazily creating it on first request with thread safety.

Key Participants & Architectural Roles

Singleton Class
Maintains private static instance and private constructor; exposes static `getInstance()`
Client
Accesses the instance exclusively through `Singleton::getInstance()`

Code Samples (Traditional OOP vs Functional Programming)

Available in C++, Python, and Java

Paradigm Contrast: Traditional OOP vs Functional / Data-Oriented

In OOP, Singleton is implemented with private constructors and static accessors. In Functional Programming, mutable global state is discouraged. Instead, "Singleton" behavior is achieved through module-level closures, Reader Monads, or passing immutable configuration records through pure function pipelines.

Advantages

  • ✓ Guarantees strict single-instance constraint
  • ✓ Controlled access to sole resource with lazy initialization
  • ✓ Avoids polluting global namespace with unencapsulated global variables

Trade-offs

  • ✗ Can mask tight coupling and introduce hidden global state
  • ✗ Difficult to unit test and mock without Dependency Injection
  • ✗ Violates Single Responsibility Principle if it handles both its business role and its lifecycle

When to Apply

  • → Managing access to shared external resources (hardware drivers, thread pools, audio engines)
  • → Global application settings or configuration registry
  • → Logging services and distributed tracer coordinators

When to Avoid

  • ! Just to pass state across functions (use parameter passing or context instead)
  • ! In multi-threaded environments where distributed clustering is used (a singleton per JVM/process is not unique across clusters)