Creational PatternsSingleton PatternMedium⏱️ ~2 min

Singleton Pattern: Structure and Implementation Strategies

Core Structure:
The Singleton Pattern involves a single class that manages its own unique instance. The structure consists of three key elements: private constructor, private static instance variable, and public static accessor method.
Singleton
- instance: Singleton (static)
- data: ConfigData
- Singleton() [private constructor]
+ getInstance(): Singleton (static)
+ getData(): ConfigData
+ setData(data: ConfigData): void
Three Implementation Strategies:
First: Eager Initialization
The instance is created at class loading time, before any thread accesses it.

class Singleton:
  instance = new Singleton() // created immediately
  
  private Singleton():
    // initialization code
  
  public static getInstance():
    return instance
Trade-off: Simple and thread-safe by default, but creates instance even if never used (wastes resources). Appropriate when the instance is lightweight and always needed.

Second: Lazy Initialization
The instance is created only when first requested via getInstance().

class Singleton:
  instance = null // not created yet
  
  private Singleton():
    // initialization code
  
  public static getInstance():
    if instance is null:
      instance = new Singleton()
    return instance
Trade-off: Saves memory if never used, but requires thread-safety mechanisms (locking) in multi-threaded environments, which adds complexity.

Third: Double-Checked Locking (Lazy with Thread Safety)
Combines lazy initialization with minimal locking overhead.

class Singleton:
  instance = null // volatile/synchronized
  
  public static getInstance():
    if instance is null: // first check (no lock)
      lock():
        if instance is null: // second check (with lock)
          instance = new Singleton()
    return instance
Trade-off: Optimizes performance by avoiding lock contention after initialization, but implementation is subtle and error-prone if not done correctly.
Interview Tip: Be prepared to discuss thread safety. Interviewers often ask how you handle concurrent access to getInstance() in multi-threaded environments.
Critical Design Decision:
The private constructor prevents external instantiation. Subclassing is also prevented because subclasses cannot call the private constructor. If subclassing is needed, consider using the Factory Pattern instead.
💡 Key Takeaways
Private constructor prevents external instantiation
Static instance variable holds the single instance
Static getInstance() method provides global access point
Eager initialization creates instance at class load time
Lazy initialization defers creation until first access
Double-checked locking optimizes thread-safe lazy initialization
📌 Examples
1Eager: DatabaseConnectionPool initialized at startup
2Lazy: HeavyResourceManager created only when needed
3Double-checked: ThreadSafeLogger with minimal locking overhead
← Back to Singleton Pattern Overview