Wednesday, April 6, 2011

Singleton Pattern

Situation:
When you want only one instance of a class, how would you proceed doing it?

Singleton Pattern:
Singleton pattern ensures that you have only one instance of a class. There are many ways to implement Singleton which has been discussed below. However there are so many gotchas that you need to think through. As Singleton is a very popular pattern, I am not going deep into how exactly it works, but will discuss only those points which are generally missed.

Implementation 1:
class Singleton implements Serializable {
  // Create a static instance immediately and
  // use this only
  // Make this variable transient so that
  // it can be serialized
  private static transient final Singleton INSTANCE
    = new Singleton();

  // You could have let the INSTANCE variable to be   // public and avoided this method.   // But doing this is a better choise as if you want   // to make this class a non-singleton, the clients   // wont get affected in this case.   public static Singleton getInstance() {     return INSTANCE;   }   // Make sure that you cant create an object   // outside this class.   // A privileged client might mess around by changing   // the accessibility of this constructor.   // To prevent this from happening,   // throw an exception inside the constructor.   private Singleton() {     throw new IllegalAccessException()   }   // This method preserves the singleton property   // when the class is deserialized.   // If this method is not provided, when the class   // is serialized and later deserialized,   // each deserialization will result in a separate   // instance.   private Object readResolve() {     return INSTANCE;   } }

Implementation 2:
A sophisticated getInstance method is provided which will lazily create the singleton instance object.
class Singleton {
  // This variable is made volatile so that this variable
  // is not cached when a processor executes it.
  // Otherwise in a multi processor environment,
  // it might cause issues as each processor will have
  // its own cached copy of this variable.
  private static volatile Singleton instance;

  public static Singleton getInstance() {
    if (instance == null) {
      synchronized(Singleton.class) {
        if (instance == null) {
          instance = new Singleton();
        }
      }
    }
    return instance;
  }

  private Singleton() { }
}

Implementation 3

This is the best way to create a singleton class. This takes care of all serialization issues and ensures that always there is only one instance. It also guarantees that nobody can hack the system to get more instances.
public enum Singleton {
  INSTANCE
}

Disadvantage:
Making a class a singleton can make it difficult to test its clients as mocking becomes very difficult. To overcome this problem, the singleton class should always be accompanied by an interface. The client should depend on the interface rather than the Singleton class directly.

1 comment:

  1. See if you can use a plugin to highlight code blocks..

    ReplyDelete