Skip to content

Creational Design Pattern: Singleton

Creational Patterns are the design patterns that works while creating object(s). Especially for lower level classes. There are multiple Patterns that can be at play at any given instance or module. Singleton pattern is the simplest design patter which involves only one class and allow only one instance of that class or itself.

Motivation

Sometimes system works in such a way that it depends on a centralized manager unit such as file Manager, Window Manager and Thread Pool Manager etc. In such scenarios we only want that there should always be just one instance of these centralized units running in memory so that they can manage all the things without conflicts with other such units.

Intent

  1. Ensures only one instance of the class ever created.
  2. Single point of access which is global, i.e. any other component can access that instance.

Example

The implantation usually involves creating one method name getInstance() which is static member of the class, a private constructor and only one instance of the class marked private and static with the class itself.

This Example works well every time but it creates the object too early in App execution, if we want to have a lazy initialization then we can write it by initializing the “INSTANCE” variable only when there is a call to the getInstance() method. This will create the INSTANCE only when it will be first required via having a null check. Check the example to see how it’ll work.

The above example has a little problem when dealing with multi-threaded environment. To make our singleton class thread safe we can add a synchronization to it to make it thread safe.

This way our class will be thread safe, but it has one other problem, synchronization kicks in every time getInstance() method is called which will add quite an over-head especially when there are many getInstance() calls.
So we can add block synchronization to tackle this problem. We only need to synchronize the construction of instance, so synchronization after null check would significantly reduce the over-head as synchronization will only be done once at the time to object creation.

The above way reduces the synchronization over-head quite a bit but there is still one problem present in the process. In case of race condition when more than one threads are waiting for synchronization block that means all of them have passed the INSTANCE null check and will create more than one INSTANCE object. To tackle this problem we can introduce a double checking process to ensure that there will ever be only one INSTANCE object. Now even in case of race condition as soon as first thread passes through the critical section and initialize INSTANCE object, no other thread will create the object they will check for null again and will skip the initialization. This is the best approach to implement the singleton pattern when multiple threads are involved and makes sure that there will ever be one and only one instance of the Singleton possible.

There is one last way we can do lazy initialization as well as thread safety by knowing how java works, it may or may not work with other languages. Also this way is little less readable but works correctly.

SingletonHolder inner class will hold only one static instance and static are only created once per class so this object will only be initialized only once. So this way thread safety is automatically guaranteed without writing any synchronizations.

Advantages of singleton

  1. Instance control: Only one instance can be created at any given moment of time ensuring that every component will access only that object only.
  2. Flexibility: It provides better control in initialization of the object then global variables plus there is an added functionality to later control the number of instances.

Disadvantages of singleton

  1. The major disadvantage is they are very hard to test while writing unit test cases. As they only work as whole process and they can hide multiple dependencies within them.
  2. Improper use of singleton can lead to more confused dependencies which will make the actual logic very hard to understand and test. Also dependency injection will not work correctly when writing test cases as there is no way to mock the States of singleton.
  3. Singleton are basically global states which is always undesirable in any application design.

Thanks for reading, this would be all for today.
Have a great time
Cheers!!

Published inDesign Patterns

Be First to Comment

    Leave a Reply

    Your email address will not be published. Required fields are marked *