Singleton design pattern ensure that only one object of a class is created and it provides a way for other classes to access its only object directly without instantiate
an object of the class. It is one of the simplest creational design patterns as it provides a way to create only one object of a class.
Sometimes, we want only one instance of a class like when only object is needed for centralized processing of any shared resources. Other examples where singleton classes are
useful are "static configuration reader class", "Logger class", "Shared database handler" etc.
- Singleton pattern ensure that only one instance of a class is created.
- Single object should be available for use by all classes.
- No class can create an instance(object) of singleton class using new operator.
Structure of the Singleton Design Pattern
- Private Constructor : The class has a private constructor to prevent external instantiation.
- Private Static Instance : The class contains a private static instance of itself.
- Public Static Method : The class provides a public static method that returns the instance. If the instance doesn't exist, it is created; otherwise, the existing instance is returned.
Advantages of Singleton Design Pattern
- Global Point of Access : The singleton instance provides a global point of access to its services or resources. This simplifies the way other classes interact with the singleton, as they can easily obtain the instance and access its methods.
- Reduces Global Variable Use : Singletons provide an alternative to global variables by encapsulating the instance within the class. This helps avoid the potential downsides of using global variables, such as unintended modifications and namespace pollution.
- Single Instance : The primary advantage of the Singleton pattern is that it ensures a class has only one instance. This instance is globally accessible, making it easy to coordinate actions or share resources across different parts of the system.
- Lazy Initialization : The Singleton pattern allows for lazy initialization, meaning that the instance is created only when it is first requested. This can be beneficial in scenarios where the instantiation of the object is resource-intensive or where the object is not always needed.
- Resource Sharing : Singletons are useful for scenarios where multiple parts of a system need to share a common resource, such as a database connection pool, configuration settings, or a logging service. The singleton instance serves as a shared resource manager.
- Improved Memory Management : By having a single instance, the Singleton pattern can help improve memory management. Instead of multiple instances of the same class, there is only one instance, reducing memory consumption and improving the overall efficiency of the system.
- Prevents Unnecessary Instantiation : By controlling the instantiation process within the singleton class, the pattern prevents unnecessary creation of instances. This can be crucial in scenarios where creating multiple instances could lead to inefficiencies or unexpected behavior.
Implementation of Singleton Design Pattern
The implementation of a singleton pattern is very simple as it involves only one class which is responsible for creating an static member of itself and the returning the reference to the static member. A Singleton class contains a private constructor, a static member of "Singleton" class and a public static method that returns a reference to the static member.
Steps to implement singleton patternLet, the name of singleton class is SingletonDemo.
- Define a private static member of "SingletonDemo" class. It will contain the reference of single object.
- Define all constructors of SingletonDemo class as private, so that any class cannot create instance of SingletonDemo using new operator.
- Define a public static factory method, that returns the static single instance of SingletonDemo class to the caller. Other classes can call this method to get an instance of SingletonDemo class.

We can create single instance of a class either at load time(Early initialization) or later when it is required first time (Lazy initialization).
Singleton pattern program in Java using Early Initialization
Creating a Singleton class "SingletonDemo.java". It creates an object of SingletonDemo during load time.
public class SingletonDemo { // create an object of SingletonDemo // instance will be created at load time private static SingletonDemo singleObj = new SingletonDemo(); // A private constructor private SingletonDemo(){} // A public method to return singleton object to caller public static SingletonDemo getInstance(){ return singleObj; } public void doSomething(){ System.out.println("Single Object of SingletonDemo class"); } }
Creating a Client class "SingletonDemoClient.java" which uses the only instance of SingletonDemo.
public class SingletonDemoClient { public static void main(String[] args) { // get singleton object of SingletonDemo class SingletonDemo instance = SingletonDemo.getInstance(); // call some method of singleton object instance.doSomething(); } }
Output
Single Object of SingletonDemo class
Singleton pattern program in Java using Lazy Initialization
Creating a singleton class "SingletonDemoLazy.java", which creates an object when it is requested first time.
public class SingletonDemoLazy { private static SingletonDemoLazy singleObj = null; private SingletonDemoLazy(){ } /* It will ceate an instance of SingletonDemo duirng first call, otherwise returns existing object */ public static synchronized SingletonDemoLazy getInstance() { if (singleObj == null) { singleObj = new SingletonDemoLazy(); } return singleObj; } }
Best Practices of Singleton Pattern
- Private Constructor : Always make the constructor of your singleton class private. This prevents external classes from creating instances and ensures that the singleton class controls its instantiation.
- Static Instance : Use a private static instance variable to hold the unique instance of the class. This variable should be final to ensure that it is assigned only once.
- Thread Safety : Implement thread safety to handle multiple threads attempting to access the singleton instance simultaneously. This is crucial to avoid race conditions and ensure that the singleton remains a single, unique instance.
- Public Static Method : Provide a public static method that acts as a global access point to the singleton instance. This method should either create the instance if it doesn't exist (Lazy Initialization) or return the existing instance (Eager Initialization or Bill Pugh Singleton).
- Enum Singleton : Consider using an enum to implement a singleton, as suggested by Joshua Bloch in "Effective Java." Enums provide built-in support for a single, unique instance, and they handle serialization and reflection issues.
- Dependency Injection : Consider using dependency injection frameworks to manage the lifecycle of singleton instances. This can simplify the handling of dependencies and reduce the complexity of your code.
- Testing and Mocking : Design your singleton class to be testable. Avoid hard-coding dependencies, and use dependency injection to facilitate testing. Additionally, consider providing a way to reset the singleton instance during testing
- Lazy Initialization with Holder Class : If you choose Lazy Initialization, consider using the Bill Pugh Singleton approach with a static inner helper class. This method ensures thread safety without the need for explicit synchronization in the getInstance method
- Keep it Simple : Strive for simplicity in your singleton implementation. Avoid unnecessary complexities or variations unless they are truly required for your specific use case.
- Document the Singleton Intention : Clearly document the intention of your singleton class, explaining why it needs to be a singleton and how it should be used. This documentation helps other developers understand the design decisions and use the singleton appropriately.
Related Topics
State Design Pattern |
Factory Design Pattern |
Mediator Design Pattern |
Observer Design Pattern |
Interpreter Design Pattern |
List of Design Patterns |