Wednesday, July 15, 2015

Singleton pattern exposed

Today we are going to look in to one of the most common pattern used in Software Development. That is Singleton Pattern.

Before moving forward let me give you a brief description of what is a Design Pattern and how it is useful in one or more ways?

What is a design pattern?
          In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design.- Wiki

Now the statement is quite clear that it is not a rocket science and it is just the way of solving a problem which is common in the market.

Ok, now when we understand the basic idea of the design patterns let us take a look on to its types or in other words categories.

Categories:
          There are 4 categories under which the design patterns are divided. These are as follows:
  1. Creational Patterns
  2. Structural Patterns
  3. Behavioral Patterns
  4. Concurrency Patterns
I will not go in the inside of these because it would be a totally new and big topic to discuss but just want to give you an idea that Singleton Pattern is one of these patterns and comes under Creational Pattern.

Now we got the info regarding the patterns and their categories. Let us now take the info regarding the Singleton pattern as a particular.

Singleton Pattern:
          In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system.

Ok, so if you need an object to be instantiated once, per JVM per Application  we use singleton pattern to achieve this.


The above diagram shows a basic idea of how singleton works.

Now there are many ways of creating singleton objects. 
  1. Eager Initialization, without static block and so no exceptional handling.
  2. Eager Initialization, with static block and so with/without exception handling.
  3. Lazy initialization
  4. Thread safe initialization
Some of the points that we have to take care about are:
  1. Reflection can break the nature of Singleton object.
At last we will look in to the Enum style of creating the singleton.
  1. Enum Singleton
Lets see  each one of the above style 1 by 1.
  1. Eager Initialization, without static block and so no exceptional handling.
             
    It is pretty basic and easy to use.

    Example:
    public class  SingletonClass{
    public static final String singleton = "I am singleton";
    }

  2. This is very easy to use and also easy to understand but as you can see it is eager in nature which means we have to create the object beforehand that means the object is in memory even if we don't want to use it.

  3. Eager Initialization, with static block and so with/without exception handling.
             
    This way is same as the previous one as in this also we create the object beforehand but the only difference is that the object is created in a static block which gives us the opportunity to use exceptional handling if we want to.

    Example:
    public class  SingletonClass{
    public static String singleton;
    static{
    try{singleton = "I am singleton";}
    catch(Exception ex){System.out.println("You can handle exception here");}
    }
    }

    This is great when we know the creating the object beforehand not make any big impact on the system but in real world scenario mostly the database connection template(in case of Spring) and hibernate template are used in a singleton manner which are very heavy objects in nature and so creating them beforehand is not a good way.

  4. Lazy initialization.
             
    This is useful to make sure that the object is created only when it is needed by any class in a JVM per application

    Example:
    public class SingletonClass {
    private static SingletonClass instance;
    private SingletonClass(){} // (3.A)
    public static SingletonClass getInstance(){
    if(instance == null){ // (3.B)
    instance = new SingletonClass();
    }
    return instance;
        }
    }

    If you look on to this example at equation (3.A) you find that we have made the constructor private in nature thus restricting the creation of the object for the class, also in equation (3.B) we have checked for nullness of the object which makes sure that only one object is created for this class.

  5. Thread safe initialization.
             
    Thread safe initialization is very important for a singleton pattern to work correctly. If you look on to equation (3.B) you will find out that this is the place that will make the things messy as it may be the chance that 2 threads of  the application enters this code and tries to create to different objects of the instance which in turn breaks the overall meaning of the pattern. Now in order to achieve thread safe initialization we have 2 modes:
    • Either go for synchronization block
    • Either go for double check

      Synchronization Block:
                
      public class SingletonClass {
      private static SingletonClass instance;
      private SingletonClass(){} // (4.A)
      public static synchronized SingletonClass getInstance(){//(4.B)
      if(instance == null){ // (4.C)
      instance = new SingletonClass();
      }
      return instance;
          }
      }

      If you look at equation 4.B, the synchronized keyword makes sure that only 1 thread has the access to this function and will create only 1 instance of the instance but the problem here is the efficiency, as if you see the overall speed of the check will be affected greatly since only 1 thread has the access to the function.

      Double Check:     
      public static Singleton getInstance(){//(4.D)
          if(instance == null){
              synchronized (Singleton.class) {//(4.E)
                  if(instance == null){
                      instance = new Singleton();
                  }
              }
          }
          return instance;
      }

      In this example equation 4.D makes sure that multiple threads can access the function and thus not affecting the efficiency and equation 4.E will place the lock on the block and recheck of the condition, this is good to achieve the thread safe creation of  the object but it is still the overhead.
Using reflection to break singleton pattern from above styles.
          The reflection is an API provided by Java that gives you the functionality to manipulate the objects in the run time. Reflection is commonly used by programs which require the ability to examine or modify the run time behavior of applications running in the Java virtual machine.

Here I am presenting the code example that can break the functionality of the Singleton pattern and thus ruins everything of singleton pattern.

Example

class Singleton {
public static final Singleton INSTANCE = new Singleton();
}
public class EnumSingletonTest{
public static void main(String[] args) {
Singleton ins1 = Singleton.INSTANCE;
Singleton ins2 = null;
try{
Constructor[] constructors = Singleton.class.getDeclaredConstructors();
for (Constructor constructor : constructors) {
                                //Below code will destroy the singleton pattern
                                constructor.setAccessible(true);
                                ins2 = (Singleton) constructor.newInstance();
                                break;
                        }
        System.out.println(ins1.hashCode());
        System.out.println(ins2.hashCode());
}catch(Exception ex){
System.out.println("Hello");
}
}
}
Output:
360637413
1034148457

The output clearly showing that both the objects are different and unique and not the same which is the promise of the singleton pattern.

Now lets look on to the Enum style of creating the singleton objects:
  1. Enum Singleton.
              
    This is something that I have created the page. This is the best way of creating the singleton object and also not worrying about the  thread safe creation and eager creation. The enum singleton pattern is by default thread safe in nature and is also easy to use.


    Example:
    enum EnumSingleton {
    INSTANCE;
    private final String var1;
    private EnumSingleton(){
    var1 = "I am initialised now you can use me";
    System.out.println("I am private constructor");
    }
    public String getVar1() {
    return var1;
    }
    }
    public class EnumSingletonTest{
    public static void main(String[] args) {
    System.out.println(EnumSingleton.INSTANCE.getVar1());
    }
    }

    One more point to be noted that Enum singleton also restricts creation of new object by the use of Reflections. If we tries to use it, the program throws an Exception.java.lang.IllegalArgumentException: Cannot reflectively create enum objects

No comments:

Post a Comment