Singleton pattern: Design Patterns
This is the most simple and clean Creational Design pattern.
We usually have times in our architecture and design of software where we need to use an object of a class but require only a single instance of it across the software. This type of single instance of a class is used widely in various applications.
Now the question is, who will instantiate and maintain the constraint that only one instance of the class is created and only that particular instance is being shared across all the other client code that demands it. Well, if we let some external class handle this constraint, then we have a tight coupling and dependency between the two classes.
So how do we ensure our problem is solved?
We have the singleton pattern that helps us to monitor and ensure our design goes as expected.
The class which needs to be instantiated once and shared across globally is called the Singleton class. In this design, the Singleton class itself is responsible to create and maintain only a single instance of itself. Any other client code when demands its object, it returns the same created object to all of them.
Singleton Pattern says that just “define a class that has only one instance and provides a global point of access to it”.
In other words, a class must ensure that only single instance should be created and single object can be used by all other classes.
There are two forms of singleton design pattern:
- Early Instantiation: creation of instance at load time.
- Lazy Instantiation: creation of instance when required.
Advantage of Singleton design pattern
Saves memory because object is not created at each request. Only single instance is reused again and again.
Usage of Singleton design pattern
Singleton pattern is mostly used in multi-threaded and database applications. It is used in logging, caching, thread pools, configuration settings etc.
What is present in the Singleton design pattern?
In the singleton class, we need to have static member of class, private constructor and static factory method.
- Static member: It gets memory only once because of static, it contains the instance of the Singleton class.
- Private constructor: It will prevent to instantiate the Singleton class from outside the class.
Steps to create a basic Singleton pattern.
To implement Singleton pattern, we have different approaches but all of them have following common concepts.
- Private constructor to restrict instantiation of the class from other classes.
- Private static variable of the same class that is the only instance of the class.
- Public static method that returns the instance of the class, this is the global access point for outer world to get the instance of the singleton class.
Implementation
We shall implement this in Java. All codes are available in the Github repository.
Eager initialisation
In eager initialisation, the instance of Singleton Class is created at the time of class loading, this is the easiest method to create a singleton class but it has a drawback that instance is created even though client application might not be using it.
Here is the implementation of static initialisation singleton class.
The Client code (Main function) would call the instance in the following way:
Static block initialisation
It is similar to eager initialisation, except that instance of class is created in the static block that provides option for exception handling.
Both eager initialisation and static block initialisation creates the instance even before it’s being used and that is not the best practice to use.
Lazy Initialisation
It creates the instance in the global access method. Here is the sample code for creating Singleton class with this approach.
The above implementation works fine incase of single threaded environment but when it comes to multithreaded systems, it can cause issues if multiple threads are inside the if loop at the same time. It will destroy the singleton pattern and both threads will get the different instances of singleton class.
We can have different ways to create a thread-safe singleton class.
Thread Safe Singleton
The easier way to create a thread-safe singleton class is to make the global access method synchronised, so that only one thread can execute this method at a time. General implementation of this approach is like the below class.
Above implementation works fine and provides thread-safety but it reduces the performance because of cost associated with the synchronised method, although we need it only for the first few threads who might create the separate instances.
To avoid this extra overhead every time, double checked locking principle is used. In this approach, the synchronised block is used inside the if condition with an additional check to ensure that only one instance of singleton class is created.
Bill Pugh Singleton Implementation
Java memory model prior to Java 5 had a lot of issues and above approaches used to fail in certain scenarios where too many threads try to get the instance of the Singleton class simultaneously.
So, Bill Pugh came up with a different approach to create the Singleton class using a inner static helper class.