Saturday, August 27, 2011

Singleton Pattern in Java

In "Set Theory", A singleton set has always only one element, Similarly, Singleton class in Java has only one object. Sometimes it is the requirement to have only one instance of a class, for example, Logically you should have only one instance of 'Download Manager', 'Windows Task Manager' is only one, Factory class in Factory pattern has to be singleton, etc.

Common uses of Singleton pattern:
1. is used in other patterns like, Factory, Abstract Factory, Builder, Facade patterns etc.
2. is used in State Object pattern as state object
3. Is preferred over global variables as lazy initialization is possible with singleton objects.

Intent in Implementation:
1. Implementation should ensure that only one object gets created.
2. Global point of access should be there. Even global variables can be used for this purpose but Singleton has its own advantages.
3. Lazy initialization implementation (optional, if your application demands it implement it)

Why prefer Singleton over global variables?
Global variables could be resource intensive as they will acquire memory as soon as your application starts whereas Singleton initialization can be deferred.

Implementations:You will find many implementations of Singleton pattern available, we will try to cover the common ones.
  1. UML Diagram for the same is given below. This implementation does not use lazy initialization and provides global access to the object through static method

    Image Source: Wiki
    Code Listing 1
    /**
     * @author Dharmvir Singh
     *
     */
    public class Singleton {
    	/* restrict access using private modifier
    	 * Below variable will be initialised at the class loading time
    	 */
    	private static final Singleton singleton =  new Singleton();
    	// No one can create object from outside using the constructor
    	private Singleton(){}
    
    	// Below static method is global point of access
    	public static Singleton getInstance(){
    		return singleton;
    	}
    }
    
    Advantage of above implementation is it is thread safe.
    Disadvantages include deserialization issues,object gets initialized at the class loading time, In case of different class loaders, you might get different objects

  2. UML is same as above. We will slightly modify our above class to incorporate lazy initialization. So, We call our class "LazySingleton"
    Code Listing 2
    /**
     * @author Dharmvir Singh
     *
     */
    public class LazySingleton {
    	private static LazySingleton singleton ;
    	// No one can create object from outside using the constructor
    	private LazySingleton(){}
    
    	/* Below static method is global point of access
    	 * Object is created when the method is called for
    	 * the first time and then same object gets returned
    	 */
    	public static LazySingleton getInstance(){
    		if(singleton == null){
    			singleton = new LazySingleton();
    		}
    		return singleton;
    	}
    }
    
    Above implementation used deferred initialization but is not thread safe. To know what issues you might face in implementing Singleton in Java, see my article: Java Singleton Pattern: Breaking the pattern

    There are other implementations available as well. Let us see them as well
  3. Bill Pugh's solution: He provided a thread-safe solution. Here is the code listing
    public class Singleton {
       // Private constructor prevents instantiation from other classes
       private Singleton() {
       }
     
       /**
        * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
        * or the first access to SingletonHolder.INSTANCE, not before.
        */
       private static class SingletonHolder { 
         public static final Singleton instance = new Singleton();
       }
     
       public static Singleton getInstance() {
         return SingletonHolder.instance;
       }
     }
    
  4. Singleton using Enum in Java:Joshua Bloch in the second edition of his book "Effective Java" has claims that "a single-element enum type is the best way to implement a singleton". Here is the code listing:
    public enum EnumSingleton {
    	INSTANCE;
    }
Why Singletons are bad
  1. Unit testing of singleton class and its dependent classes is difficult.Check out the discussion
  2. Singleton classes cannot be reused. For example suppose your controller in MVC is singleton, you cannot use it for any other purpose
  3. Singletons cannot be extended. For example, if you try to subclass a singleton, firstly you cannot, somehow if you figure that out you will land up in many other problems
Relevant References:
  1. Wiki
  2. JavaWorld:Singleton
  3. JavaBeginner:Singleton
  4. Use your singletons wisely

1 comment: