Pages

Saturday, April 4, 2015

Design Patterns : Singleton - One & only ONE Object

You may also like to see:

What is Design Pattern?


In programming, a design pattern is a general solution to a commonly occurring problem you find again and again in software design. A design pattern is a template for solving a problem and it can be use in different situations.

Singleton Pattern


Singleton Pattern is the most known design pattern and it is the simplest in terms of class diagram. It contains only one class. Singleton is a class which can be instantiate only one time and same instance get utilize in complete application. Singleton class don't take any parameters while creating an instance then same object might not be usable if different parameters are passed to initialized the class. The singleton pattern gives global point of access to instance like global variable but we can create our object only when its needed.


When to use Singleton?


There are many objects in an application for which we need a same instance always for example: logging objects, caches, dialog boxes, thread pools, app-settings or registry settings objects and object handle devices like printer etc. In fact many of these objects may cause unexpected application behavior or cause overuse of resources if more than one instance get instantiate.

Is Singleton really an anti pattern?


Before going to actual implementation of Singleton pattern, there are some pitfalls with singleton pattern. It is really complex and difficult to write unit test for a singleton class. Because singleton object maintain the state so your multiple test cases can behave weird if you did not reset the global state of singleton class between two isolated test cases. The ideal way is to use IoC/DI container (i.e, spring etc). These containers allow you to create singleton instance but also give you the ways to modify this behavior according to situation like for unit tests.

Implementation of Singleton Pattern


Any public class can be instantiate as new Object() but if class is public then at any point new Object() will instantiate a new object of the class.

So that means if class is public we cannot stop the multiple instances of the class. What if we make the class private? Will this stop the multiple instances of class? NO, as private class often declared as nested class and can be accessible within parent class but there can be multiple instance of private class within parent public class. So making class private will not make it singleton.

What if we make the constructor of class private?

public Singleton
{
  private Singleton()
  {
  }
}

What does this code means? It cannot be instantiate as its constructor is private and can only be called within the class. So now we have a class which cannot be instantiate but for Singleton we need ONE OBJECT which is not possible in our code.

As we know private constructor can only be invoke within the class that means we actually can instantiate within the class. so what if we create a static method which returns us an object.

public Singleton
{
  private Singleton()
  {
  }

  public static Singleton GetSingletonInstance()
  {
     return new Singleton();
  }
}

Now we can get class instance using static function Singleton.GetSingletonInstance(); It is still returning new instance each time but now we can easily change the code to return the same instance:

public Singleton
{
  //private static variable to hold the instance
  private static Singleton _uniqueInstance = null;

  //private constructor can only be call within class
  private Singleton(){}

  //static function to get same instance always
  public static Singleton GetSingletonInstance()
  {
    if(_uniqueInstance == null)
    {
      _uniqueInstance = new Singleton();
    }
    return _uniqueInstance ;
  }

  //other required class methods
}

So now our code will check the static instance holder variable and if it is null which means it is not loaded before it will get initialize and will be return and for each next call same instance will be return.

So are we done with singleton? What if application has multiple threads? and two of threads at the same time called the Singleton.GetSingletonInstance();

Thread 1 will check if(_uniqueInstance == null) which will be true
Thread 2 will check if(_uniqueInstance == null) which will be true

So now we have two different instance of our Singleton object within two threads. So it is still not singleton object. Our above implementation is not thread safe.

In c# we can use lock to make it thread safe. Lock will make sure only one thread at a time can have access to instance initiator code.

public Singleton
{
  //private static variable to hold the instance
  private static Singleton _uniqueInstance = null;
  
  private static readonly object lockObject = new object();

  //private constructor can only be call within class
  private Singleton(){}

  //static function to get same instance always
  public static Singleton GetSingletonInstance()
  {
     lock(lockObject)
     {
       if(_uniqueInstance == null)
       {
         _uniqueInstance = new Singleton();
       }
       return _uniqueInstance ;
     }
  }

  //other required class methods
}

This implementation is thread safe as lock statement will make sure only one thread can use the code after locking it. Which means when thread 1 will invoke the lock() the second thread will be hang to use the code until thread 1 is completed with its executions.

As we can see it is thread safe but it will effect on performance as each time instance get requested lock will be created. But we actually need the lock for only first time when instance get initialized after that if multiple thread go for getting the instance at the same time will get the same instance as if(_uniqueInstance == null) will be false always.

How to optimize the performance?


If you think lock within GetSingletonInstance() will not cost you much, so there is no need to change in implementation. You are good with above code implementations. Otherwise you can do one of following options.

Without lock - Removing lazy instance creation


One option is to remove the lazy instance creation, instead we go with eager created instance.

public Singleton
{
  //private static variable with initialize instance
  private static Singleton _uniqueInstance = new Singleton();

  //private constructor can only be call within class
  private Singleton(){}

  //static function to get same instance always
  public static Singleton GetSingletonInstance()
  {
    //as we already initialize the static instance so just return it
     return _uniqueInstance;
  }

  //other required class methods
}

So now our static variable has the instance and it will be return for each thread. It is thread safe but it has removed the concept of on demand object creations which means your instance will be created whether your application need it or not.

Double checked locking


With double checked locking we firstly check whether instance is null or not.If it is null then we lock the inner-code. It means only first instance creation will require the lock after that all thread will get the same instance without lock.


public Singleton
{
  //private static variable to hold the instance
  private static Singleton _uniqueInstance = null;
  
  private static readonly object lockObject = new object();

  //private constructor can only be call within class
  private Singleton(){}

  //static function to get same instance always
  public static Singleton GetSingletonInstance()
  {
     if(_uniqueInstance == null)
     {
       //if _uniqueInstance is null then lock
       lock(lockObject)
       {
          //recheck here bcos if second thread is in queue it will get it false
          if(_uniqueInstance == null)
          {
             _uniqueInstance = new Singleton();
          }
       }
     }
     return _uniqueInstance ;
  }

  //other required class methods
}

So now if two thread gets if(_uniqueInstance == null) true only one thread will go forward to create the instance, second will wait for first thread to complete the execution.

Conclusion


As we noticed there are multiple ways to implement the singleton pattern and it is completely on the situation to opt the most suited option for the scenario. Each implementation has its pros and cons, so always go according to application situation.

You may also like to see:

3 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. If the singleton instance contains state (and it probably does or else you would use a static class [java: a class with a private constructor and only static methods/properties]), then you must also make sure the implementation is thread safe around all state-full fields. It is much easier for debugging and avoiding race conditions if you take the extra effort put in a design where the state object be stashed in something the SystemCache, and then new instances of the singleton can be created with a dependency on an IMemoryCache. then unit testing as well as lose coupling is achieved.

    Refer to: https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.default(v=vs.110).aspx

    ReplyDelete
  3. The example demonstrating double-checked locking is broken. You should make the unique instance volatile.

    ReplyDelete