design patterns 4 min read • 2024-12-27
The Singleton Design Pattern Explained
Master the Singleton pattern, one of the most commonly used design patterns for ensuring only one instance of a class exists.
Java Design Patterns Creational Patterns Singleton
The Singleton Design Pattern Explained
The Singleton pattern is a creational design pattern that ensures a class has only one instance and provides a global point of access to it.
What is the Singleton Pattern?
The Singleton pattern restricts the instantiation of a class to a single object. This is useful when exactly one object is needed to coordinate actions across the system.
When to Use Singleton?
- When you need exactly one instance of a class
- When you need global access to that instance
- When the instance should be initialized lazily
- When you want to control access to shared resources
Implementation Approaches
1. Eager Initialization
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
2. Lazy Initialization (Thread-Safe)
public class LazySingleton {
private static volatile LazySingleton instance;
private LazySingleton() {}
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
if (instance == null) {
instance = new LazySingleton();
}
}
}
return instance;
}
}
3. Bill Pugh Solution (Recommended)
public class BillPughSingleton {
private BillPughSingleton() {}
private static class SingletonHelper {
private static final BillPughSingleton INSTANCE = new BillPughSingleton();
}
public static BillPughSingleton getInstance() {
return SingletonHelper.INSTANCE;
}
}
Use Cases
- Database connections
- Logger classes
- Configuration objects
- Caching mechanisms
- Thread pools
Advantages
- Controlled access to the sole instance
- Reduced namespace pollution
- Permits a variable number of instances (can be modified)
- More flexible than class operations
Disadvantages
- Violates Single Responsibility Principle
- Can mask bad design
- Requires special handling in multithreaded environments
- Difficult to unit test
Conclusion
While Singleton is useful, use it sparingly. Consider dependency injection frameworks for better testability and flexibility.