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.
| Component | Role |
|---|---|
| Private static instance | Holds the singleton object |
| Private constructor | Prevents 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.
| Technique | Thread Safety | Performance |
|---|---|---|
| Synchronized method | Safe | Slower |
| Double-checked locking | Safe with volatile | Faster |
| Initialization-on-demand Holder | Safe | Fastest |
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._instanceReferences
- 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.