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 : To its services or resources, the singleton instance offers a global point of access. Because they can quickly retrieve the instance and use its methods, other classes can now interact with the singleton in a simpler manner.
- Reduces Global Variable Use : By enclosing the instance inside the class, singletons offer an alternative to global variables. By doing this, the possible drawbacks of utilizing global variables—such as namespace pollution and accidental modifications—are reduced.
- Single Instance :The Singleton pattern's main benefit is that it guarantees a class has just one instance. Because this instance is globally available, coordinating activities or sharing resources across various system components is simple.
- Lazy Initialization : An instance is only created when it is first requested thanks to the Singleton pattern, which permits lazy initialization. This can be useful in situations where the object is not always required or where the object's instantiation requires a lot of resources.
- Resource Sharing : Singletons come be handy in situations when a database connection pool, configuration settings, or a logging service are among the resources that several components of a system must share. The shared resource manager is the singleton instance.
- Improved Memory Management : The Singleton pattern, which only has one instance, can aid in better memory management. There is only one instance of the class rather than several, which lowers memory usage and boosts system performance overall.
- Prevents Unnecessary Instantiation : The pattern avoids needless instance creation by managing the instantiation process inside the singleton class. This can be important in situations when running several instances might result in unexpected behavior or inefficiencies.
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; } }
Guidelines for Effective Singleton Pattern Implementation
- Private Constructor : It is advisable to designate the constructor of your singleton class as private. This prevents external classes from generating instances and ensures that the singleton class maintains control over the instantiation process.
- Static Instance : Employ a private static instance variable to store the unique instance of the class. This variable should be declared final to guarantee that it is only assigned once.
- Thread Safety : Implement thread safety mechanisms to address situations where multiple threads attempt to access the singleton instance concurrently. This is vital for avoiding race conditions and preserving the singleton as a singular, exclusive instance.
- Public Static Method : Endow the singleton instance with a public static method accessible from any part of the code. This method, when invoked, should either create the instance if it doesn't exist yet (Lazy Initialization) or return the pre-existing instance (Eager Initialization or Bill Pugh Singleton).
- Enum Singleton : Joshua Bloch proposes using an enum to create a singleton, as outlined in "Effective Java." Enums inherently support the creation of a single, unique instance, and they handle concerns like serialization and reflection.
- Dependency Injection : Explore the use of dependency injection frameworks to manage the lifecycle of singleton instances. This can streamline dependency handling and reduce code complexity.
- Testing and Mocking : Design your singleton class with testability in mind. Avoid embedding dependencies in a rigid manner, and leverage dependency injection to facilitate testing. Additionally, provide a means to reset the singleton instance during testing.
- Lazy Initialization with Holder Class : If opting for Lazy Initialization, contemplate adopting the Bill Pugh Singleton approach with a static inner helper class. This technique ensures thread safety without necessitating explicit synchronization in the getInstance method.
- Keep it Simple : Aim for simplicity in your singleton implementation. Steer clear of unnecessary intricacies or variations unless they are genuinely essential for your specific use case.
- Document the Singleton Intention : Clearly mention the purpose of your singleton class in documentation, elucidating why it must be a singleton and how it should be utilized. Such documentation aids other developers in comprehending the design rationale and employing the singleton appropriately.
Related Topics
State Design Pattern |
Factory Design Pattern |
Mediator Design Pattern |
Observer Design Pattern |
Interpreter Design Pattern |
List of Design Patterns |