Singleton Design Pattern in Depth
As you know, software design patterns are well-defined code snippets can be used to solve the well known common problems in software developments. Design patterns are divided into three categories as,
- Creational
- Structural
- Behavioural.
Among these three categories, Singleton design pattern is categorized under the creational design patterns. Under the creational design patterns, we can define them as, creation of objects using various mechanisms for improving the flexibility and reusability of the code.
Singleton Design Pattern
As I mentioned at the start of this article, we can expect some kind of object creation strategy using this singleton design pattern. Using this singleton design pattern, we can create an only one single object for a class. To achieve this purpose, simple strategies are used in the concept. And some modifications are added to the main concept to improve the usability of the singleton concept. More information about them will be explained in the later part of this article.
Now, we initially discuss how simply achieve the simple object creation concept in the singleton design pattern. If there are different type of approaches in singleton design pattern implementation in Java, there are few common things need to be in the code.
- Private constructor :- used to restrict the instantiation of the class from other classes.
- Private static instance of the class :- only one instance of the class
- public static method :- that is used to return the object from the class
Now, we consider the different approaches for the singleton design pattern implementation.
1. Eager Initialization
This is also called as early instantiation. The instance of the singleton class is created at the class loading time.
This is the simple and easiest representation of the singleton in Java. Consider this type of the singleton we can see a drawback of instantiation even though the that is not used by the application and also this variant does not support any option to exception handling. If the client application does not want to use lots of resources, this will be the appropriate type.
2. Static block initialization
Now, you know about the eager initialization in singleton design pattern, and you know the drawbacks of exception handling with the explained method. That is overcoming with this type of method.
In this method also has the appearance of the eager initialization. This static variable and static block is loaded when class loading time. And these two types created the object before it is being used.
3. Lazy Initialization
Lazy initialization provides the facility to create an object when it is needed. But this approach is correctly worked with the single threaded environment, otherwise multithreaded environment behaviour violate the singleton pattern concept.
4. Thread Safe Singleton
If you want to create singleton pattern in a thread safe environment. Here, a synchronized method should be used for the object returning method. Since using the synchronization, you are allowed only to use a single thread. This is the easiest way to implement the thread safe singleton design pattern, but there are some drawbacks with this method. Before discussing them, below you can see the implementation of this method.
If above implementation is easy to understandable and implementation, it has less performance due to the usage of synchronized method. That means it sometimes takes to process, but we can implement this in an optimized way by using the double-checked locking approach. Here, below-mentioned the code snippet for using double-checked locking implementation.
5. Bill Pugh Singleton Implementation
In the memory model of the Java versions before 5th version had a lot of issues and above approaches are failed due to the too many threads try to get the instance simultaneously. As a solution for this method used in the singleton implementation. Here, this class uses an inner static helper class. And also a synchronized block or synchronized methods, not used in this type of singleton implementation. Below-mentioned the code snippet and brief explanation for what is going with the implementation.
In the mentioned code snippet, you can see the F object in the FHelper class that means it is not loaded into memory only when call the getInstance method, this class loaded and creates the instance.
6. Using Reflection to destroy Singleton Pattern
What is reflection in Java? Simply we can define, that is a process of examining or modifying the run time behaviour of a class a run time. So, then reflection behaviour can be used to destroy all the above discussed singleton design patterns methods. Here we go for an example of that.
7. Enum Singleton
As a solution for above issue, a Java enum based solution has introduced. Java enum values are instantiated only at once and globally accessible. Even in this method also drawback with lazy initialization.
Usage of Singleton Design Pattern
- For system logging, drivers objects, caching, and thread pools
- Used in core Java classes, ex: java.lang.Runtime, java.awt.Desktop
- Used other design patterns, ex: Abstract Factory, Builder, Prototype, Facade, and Fly Weight
Here is the end of the first episode of design pattern article series. If some defects or missing things here, please be kind to mention in the comments.
Thank you for reading.
Happy Coding…