In your day do day life you guys would have noticed that certain things happen in a certain specific way. For example there is a specific procedure for a police to arrest a criminal. A certain type of body movements a batsman makes before he does a batting shot, and a diver getting into a specific position before diving off into the pool. All these activities have certain patterns that each of them does. Just like that there are Design patterns that software engineers can use that can make their life easier.
In this article I will give an introduction to design patterns and talk about the Singleton Pattern. I will be using Java to implement a small example with singleton pattern.
What is Design Pattern
Design patterns are like a blueprint for an implementation. Lets say that you have a problem that you have to solve, instead of thinking from what classes to create what methods to use, you can directly use the design patterns as they are well tested reliable and flexible ways to implement your code. Simply put design patterns are well proved solution for solving specific problems or tasks.
There are multiple different types of design patterns in use, these design patterns are also known as gang of four design patterns. And those are.
- Creational Design Pattern
- Structural Design Pattern
- Behavioral Design Pattern
Lets take a brief look into what each of them are.
1.Creational Design Pattern
These types of design patterns deal with the creation of objects. With these types of patterns we wont be normally using the new keyword for creating a new object (hard coding), instead we will be implementing different patterns to implement them.
The creational design patterns are :-
- Factory Pattern
- Abstract Factory Pattern
- Singleton Pattern
- Prototype Pattern
- Builder Pattern.
In this article we will be looking at the singleton pattern which will be covered in the following sections.
Note : The reason these patters are not called gang of three is because of its creators. The design patterns book that was written in 1995 was written by four individuals.
2. Structural Design Pattern
These types of patters will determine the structure of the class that we use (relationships). These design patterns will simplify the structure by identifying relationships. So with these patterns we will be able to easily handle
The structural design patterns are :-
- Adapter Pattern
- Bridge Pattern
- Composite Pattern
- Decorator Pattern
- Facade Pattern
- Flyweight Pattern
- Proxy Pattern
3. Behavioral Design Pattern
These design patterns will be dealing with the way the objects interact and communicate with each other. These patterns will help objects to communicate with each other and stay loosely coupled.
Behavioral Design Patterns are : -
- Chain Of Responsibility Pattern
- Command Pattern
- Interpreter Pattern
- Iterator Pattern
- Mediator Pattern
- Memento Pattern
- Observer Pattern
- State Pattern
- Strategy Pattern
- Template Pattern
- Visitor Pattern
Now that we know about the different types of design patterns, lets take a look into one of the most used design pattern the Singleton Design Pattern.
Singleton Design Pattern
Singleton design pattern is one of the most used design pattern and also wrongly used design pattern out there. As the name implies singleton pattern should be used if there is a one single entity that is needed to be used by multiple different threads. Lets say that I have an application that will have a set to default function. When this function is called a default configuration must be loaded. No matter the number of people calling the function the configuration will be same, so only one instance of this object will be enough for use. I will be showing different implementations of this pattern on the following sections.
Look at the code below for the configuration class and the main method implementation.
Now if you look at the Configuration class I have made the constructor private. As the constructor is private we will not be able to create an instance of this class with the new keyword outside this class. The variable is made static so that only one per class is created. The volatile keyword will make it thread safe. Then we are using a public getter to retrieve that specific instance of the configuration that is created in the class itself. In the main method I have created two instances of the Configuration class. If I run this code both config1 and config2 will be pointing to the same object.
As you can see from the above output both of these instances are pointing to the same object.
Note : Volatile is used with static because in multi threading scenarios threads might use the static value that will be stored in the cache memory. But using the keyword volatile we will be making sure that the value of the variable will be taken directly from the main memory. So that there will not be any inconsistency issues.
Now this is the basic level implementation of the singleton design pattern. But there maybe other instances where this might not work properly, for example using the reflection API may automatically create an instance of the configuration class manually by invoking the constructor. For that we can use something like this,
As you can see above if the reflection framework tries to create an instance the if condition inside the constructor will not allow it. The if statement in the getter will check if no constructor is created if not it will create an instance at that point and return it, if it is already created it will simply return the created one.
Double locking / Double checking singleton
Now the applications that we create will be having more than one user at a time accessing the same resource, so normally we will be having a multi threading scenario. If the above singleton implementation is used we may get a scenario like this, Thread 1 will come inside getter and passes the if condition but before it creates the instance thread 2 will also pass the if condition. In this instance two different objects will be created which defeats the whole point of singleton. In order to avoid that we will be using the singleton implementation known as the Double locking which is also known as double checking singleton. Look at the below code.
In the above code the synchronized key word is used. By using this keyword I am making this thread safe, where if one thread is inside the synchronized block the other thread cannot access it. It will hold a lock on it. After it has exited the block only will another thread be able to enter it. Even if another thread enters the synchronized block, it will be failing the condition check.
Now lets say to emulate a real implementation I am also adding a method that will be returning the configuration file so the system can make the changes according to it.
Now look at the following implementation.
Note : I am calling the config file as a string just as an example of this type of implementation. Please do not take it literally 😅
Okay now if you look at the above code segments there is a method that will be returning the configuration file in the Configuration class. (This is also made thread safe). And I also called
Thread.sleep(5000) before the object is initialized to show some process time. I have also made some changes to the my app class to show the time it takes to initialize the singleton pattern while using this in a multi threaded scenario. If I run this program the following will be the output that I will be getting.
As you can see from the above image the main thread has taken around 5 seconds to create the file while the child thread doesn’t take any time to create it. This is the power of singleton pattern.
Singleton pattern are normally used in places where a single instance of a class is needed. For example a data base manager that creates connection, a printer class that will be printing a message on a receipt, a logger class that will be logging the information or as I shown above a configuration class that will set a specific configuration to the running program.
While the singleton pattern has its advantages it also has its disadvantages, heavy usage of singleton pattern may prove difficult to bugfix and also during unit testing.
In the above example I used the synchronized block inside the method instead of using it on the method itself. We can use it on the method but it is not the best use case, lets say that the method has other variables and lines of code that does not work with a shared resource. If we called it there every thread that uses the method will have to wait and start from the beginning after the lock is released. So it is best practice to use it where shared resources are used.
Another common question you may ask is why go through all this trouble instead of making this class a static. The key thing is that singleton classes are able to implement interfaces and extend classes while static is unable to. In static you can extend but it will not use inherit the instance members from its parents.
Click here for the Github link for the codes used here.
This video by Krishantha Dinesh was a huge help in creating this blog. Check it out if you can.
Design Patterns in Java - Javatpoint
A design patterns are well-proved solution for solving the specific problem/task. Now, a question will be arising in…