Definition

Concept

Singleton: creational design pattern. Purpose: restrict class instantiation to one object. Ensures controlled access: single shared instance. Provides global access point: static method or property.

Origin

Introduced by: Gang of Four (GoF). Source: "Design Patterns: Elements of Reusable Object-Oriented Software" (1994). Category: creational patterns.

Essence

Guarantee: exactly one instance. Control: centralized. Visibility: global. Encapsulation: constructor private or protected.

Purpose and Motivation

Problem Addressed

Multiple instances: may cause resource conflicts, inconsistent state, redundant operations. Need: single access point to shared resource.

Motivations

Resource management: database connections, configuration settings. Coordination: logging, caching, thread pools. Consistency: ensure uniform behavior.

Design Goal

Instance control: prevent multiple creations. Access control: provide simple global access. Lifecycle management: lazy or eager initialization.

Structure and UML

Class Diagram

Singleton class: private static instance variable, private constructor, public static method to get instance.

Key Components

Instance variable: stores singleton object. Constructor: private to restrict instantiation. Access method: static, returns instance.

UML Notation

Class box: stereotype «singleton». Attributes: -instance : Singleton. Operations: +getInstance() : Singleton.

ComponentRole
Private static instanceHolds the singleton object
Private constructorPrevents external instantiation
Public static getInstance()Returns the singleton instance

Implementation Techniques

Eager Initialization

Instance created at class loading. Simple: thread-safe by default. Drawback: resource usage if unused.

Lazy Initialization

Instance created on first request. Saves resources. Requires synchronization for thread safety.

Double-Checked Locking

Optimization for lazy init. Locks only on first creation. Reduces synchronization overhead.

Static Inner Helper Class

Uses classloader for thread-safe lazy instantiation. No explicit synchronization needed.

public class Singleton { private Singleton() {} private static class Holder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return Holder.INSTANCE; }}

Thread Safety Considerations

Issues

Race conditions: multiple threads create instances simultaneously. Data inconsistency: partial initialization.

Synchronization

Locking: synchronized methods or blocks. Overhead: performance degradation if overused.

Alternatives

Volatile keyword: prevents instruction reordering. Atomic operations: ensure integrity. Initialization-on-demand: thread-safe without locks.

TechniqueThread SafetyPerformance
Synchronized methodSafeSlower
Double-checked lockingSafe with volatileFaster
Initialization-on-demand HolderSafeFastest

Lifecycle and Initialization

Creation

Timing: eager vs lazy. Impact: resource allocation, startup time.

Destruction

Typically: no explicit destruction. Managed by garbage collector or application lifecycle.

State Management

Singleton may hold mutable state. Risks: shared mutable state leads to concurrency issues.

Advantages

Controlled Instance

Prevents multiple instances. Ensures single source of truth.

Global Access

Convenient centralized access point. Simplifies resource sharing.

Reduced Namespace Pollution

No need for global variables. Encapsulates instance inside class.

Lazy Initialization Support

Delays resource usage until necessary.

Disadvantages

Hidden Dependencies

Global access creates implicit coupling. Difficult to track object usage.

Testing Challenges

Hard to mock or replace in unit tests. Leads to brittle test code.

Concurrency Risks

Requires careful synchronization. Improper use causes race conditions.

Design Limitations

Restricts subclassing due to private constructor. Violates single responsibility principle.

Use Cases and Applications

Configuration Management

Centralizes application settings. Ensures consistent configuration access.

Logging Systems

Single logger instance. Coordinated output and formatting.

Database Connections

Connection pooling or shared connection manager.

Cache Management

Shared cache access and invalidation.

Variants and Extensions

Multiton

Multiple instances keyed by identifier. Extends singleton to controlled multiple instantiation.

Thread-local Singleton

Separate instance per thread. Avoids synchronization overhead.

Registry Singleton

Central registry of singletons. Supports multiple singleton objects.

Comparison with Other Patterns

Singleton vs Static Class

Singleton: instance-based, supports inheritance and interface implementation. Static class: no instantiation, less flexible.

Singleton vs Factory

Factory: creates objects, often multiple. Singleton: restricts to one instance.

Singleton vs Dependency Injection

DI: externalizes instance management, improves testability. Singleton: internal instance control, less flexible.

Code Examples

Java Singleton Example

public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }}

Python Singleton Example using __new__

class Singleton: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance

References

  • Gamma, E., Helm, R., Johnson, R., Vlissides, J. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1994, pp. 127–134.
  • Bloch, J. Effective Java (3rd Edition). Addison-Wesley, 2017, pp. 15–17.
  • Goetz, B. Java Concurrency in Practice. Addison-Wesley, 2006, pp. 45–49.
  • Fowler, M. Patterns of Enterprise Application Architecture. Addison-Wesley, 2003, pp. 99–104.
  • Völter, M. Pattern Languages of Program Design 5. Addison-Wesley, 2006, pp. 143–160.