Tuesday, September 11, 2012

Singleton Design Pattern Questions

Singleton Design Pattern is the basic design pattern that most of the developers seems to learn at the very early stages of their career (including me). So it is natural that there are lot questions that interviewers asked in order to see whether the person has just crammed up the definition or actually knows how to write it as well. Also, the implementation of this pattern has also changed a lot over time and a thorough knowledge of the same would mean that the person is also up to date with the new techniques.
Question 1: Explain Singleton Design Pattern?
Singleton Design Pattern means there is only one instance of an object in the Application / per classloader.

Question 2: What are the things required to implement a Singleton class?
Singleton class should have a private constructor and there is only way to create singleton instance.

Question 3: How do you implement Singleton?
In order to create a Singleton please see below:

     public class SingleTon {
         private static SingleTon INSTANCE;
         
         private SingleTon() {
         }

         public static SingleTon getInstance() {
           if (INSTANCE == null) {
                 INSTANCE = new SingleTon();
           }
           
           return INSTANCE;
         }
}
Question 4: Is the above class thread-safe?
The problem with the above class is that if two methods execute the getInstance() method, both of them might be able to create an instance and hence violating the Singleton condition. In order to achieve thread-safety, we can make the getInstance() method synchronized. as below:

     public class SingleTon {
         private static SingleTon INSTANCE;
         
         private SingleTon() {
         }

         public synchronized static SingleTon getInstance() {
           if (INSTANCE == null) {
                 INSTANCE = new SingleTon();
           }
           
           return INSTANCE;
         }
}
Question 5: In the above solution synchronizing the static method will give you a class level lock and hence have performance impact? How can you remove that?
In order to remove the synchronizing we can have a static field instantiating the Singleton as below:

     public class SingleTon {
         private static final SingleTon INSTANCE = new SingleTon();
         
         private SingleTon() {
         }

         public static SingleTon getInstance() {
           return INSTANCE;
         }
}
The problem with the above class is that if your Singleton class have lot of constructs you might end up creating them even though you may not need them. So above should only be used if the Singleton is not very heavily loaded.This type of initialization is also known as Eagerly Initialization whereas the above initialization is known as Lazy Initialization.

Question 6: How to improve the above solution incase the class is heavily loaded?
In that case we would like to delay the instantiation process as below, by using an inner static class:
public final class SingleTon {
     private static class SingleTonHolder {
              private static SingleTon INSTANCE = new SingleTon();
     }
     
     private SingleTon() {}

     public static SingleTon getInstance() {
       return SingleTonHolder.INSTANCE;
     }
}
Question 7: How do you prevent the Singleton class creation using reflection?
One way to do that is to throw an exception from the Constructor as follows:
public final class SingleTon {
     private static class SingleTonHolder {
              private static SingleTon INSTANCE = new SingleTon();
     }
     
     private SingleTon() {
        if(SingleTonHolder.INSTANCE != null) {
           throw new IllegalStateException("Already Instantiated");
        }
     }

     public static SingleTon getInstance() {
       return SingleTonHolder.INSTANCE;
     }
}
Question 8: Is there any other method that can be used to create a Singleton class?
Other method that can be used to create a Singleton class is the enum method, this solution is only applicable post Java 1.5. This is possible using Enum as:
public enum SingleTon3 {
 INSTANCE;
        // Other instance methods.
}
The advantage of using this is that, Java Memory Model guarantees that there will a single instance of the Enum and Enums are thread-safe as well.

Question 9: What do you understand by the double checked locking in Singleton pattern?
Double checked locking means that the INSTANCE is checked for NULL twice, before and after acquiring lock. Remember that it is only possible after Java 5, with the better handling of volatile fields. This may not work before Java 5.
     public final class SingleTon {
           private SingleTon INSTANCE;
     
           private SingleTon() {
             if(INSTANCE != null) {
               throw new IllegalStateException("Already Instantiated");
             }
           }

           public static SingleTon getInstance() {
               if(INSTANCE == null) {
                   synchronized(this) {
                        if(INSTANCE==null) {
                           INSTANCE = new SingleTon();
                        }
                   }
               }
               
              return INSTANCE;
           }
     }
Question 10: How do you avoid a Singleton being created by serialization?
This problem occurs when your Singleton implements Serializable. The readResolve() method will always return a new instance of the class, just like Constructor. In order to avoid this you can override the readResolve() method to return your INSTANCE as:
     public final class SingleTon {
           private volatile SingleTon INSTANCE;
     
           private SingleTon() {
             if(INSTANCE != null) {
               throw new IllegalStateException("Already Instantiated");
             }
           }

           public static SingleTon getInstance() {
               if(INSTANCE == null) {
                   synchronized(this) {
                        if(INSTANCE==null) {
                           INSTANCE = new SingleTon();
                        }
                   }
               }
               
              return INSTANCE;
           }
          
          private Object readResolve(){
            return INSTANCE;
          }
     }
This can even become more complex if your Singleton starts to manage states, as then the states have to be transient. This problem can also be handled by Enums, as the serialization is handled by the JVM.
Question 10: Why should you avoid Singleton anti-pattern or why is Singleton is an anti-pattern?
  1. In order to use Singleton we need to call getInstance(), which makes them tightly coupled to the calling object and hence makes them hard to mock while testing.
  2. They maintain their state during the lifetime of the application and hence makes unit testing difficult as you may need to execute your Junit in an order. This voids the basic principle of Unit testing that the tests should be independent of each other.
  3. They violate the Single Responsibility Priniciple, as they manage the creation and lifecycle themselves.
  4. They are generally used as a global variable and creating global variable just to avoid passing them around is a code smell.