Thursday, December 13, 2012

Singleton design pattern in examples

The singleton 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.

There are different ways of implementation.

Lazy Singleton aka Singleton with double-checked locking
public class LazySingleton {
    private static volatile LazySingleton instance = null;

    private LazySingleton() { /* do something */ }

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


Eager Singleton
public class EagerSingleton {
    private static final Singleton instance = new EagerSingleton();

    private EagerSingleton() {}

    public static EagerSingleton getInstance() {
        return instance;
    }
}


Buggy Eager Singleton
If you forgot to declare an private constructor of the singleton, the the users of the class might have created new instances with no restriction. Here is an example
public class WrongEagerSingleton {
    private static final WrongEagerSingleton instance = new WrongEagerSingleton();

//    private WrongEagerSingleton() {} - if you forget to declare an private constructor

    public static WrongEagerSingleton getInstance() {
        return instance;
    }
  
  public static void main(String... aArgs){
    EnumSingleton fatGuy = EnumSingleton.INSTANCE;
    fatGuy.doSomething();
  
    WrongEagerSingleton fatGirl = new WrongEagerSingleton(); // this DOES compile, so we have NOT real singleton
  }

}



Singleton via Enum
Some people tell that this is the recommended way.
public enum EnumSingleton {
  INSTANCE;

  /**Add some functionality to the object. */
  public void doSomething(){
    // ala bala
  }

  /** Demonstrate use of EnumSingleton. */
  public static void main( String... aArgs ){
    EnumSingleton fatGuy = EnumSingleton.INSTANCE;
    fatGuy.doSomething();
  
    //doesn't compile :
    //EnumSingleton fatGuy = new EnumSingleton();
  }
}


No comments:

Post a Comment