Wednesday 26 May 2010

Singleton using Enum

Was chatting in the pub last night about singletons, in particular the problems associated with a singleton not being a singleton in the face of serialisation, improper synchronization, reflection and improper subclassing . An interesting solution has presented itself as of java 1.5 in the form of the java enum. Java enums are much more powerful than the equivalents in C++, but much underused as they can take a bit of getting used to.

The enum with a single value effectively gives you the single instance that the rest of the ‘class’ hangs off. It is functionally equivalent to the ‘public static final’ instance, where the instance is in the form of a single enumerated value. You can also provide a static getInstance(), although you can’t then hide access to the enumerated value. It can’t be sub-classed, cant be cloned, and although it can be serialised, de-serialisation can’t create a new instance. It also has the advantage of being able to implement an interface, and this is important to allow isolated unit testing of the consumers of the singleton.

public interface Valueable {

  public int getValue();
  public void setValue(int value);
}

public enum OnlyOneOfMe implements Valueable {

  INSTANCE;

  private int value;

  public static OnlyOneOfMe getInstance() {
    return INSTANCE;
  } 

  public int getValue(){
    return this.value;
  }

  public void setValue(int value){
    this.value = value;
  }
}

public class SingletonTest {

  Valueable onom = OnlyOneOfMe.getInstance();

  @Test    
  public void doTest() {
    onom.setValue(1);
    int value = onom.getValue();  
  }
}

In summary, this technique is powerful because it makes use of language and JVM spec absolute guarantee’s that there will only ever be one of them per JVM. This is not a solution that I have ever seen in real code, but as far as I can see it looks superior to any other singleton solution, provided you don’t want to lazy load.

No comments:

Post a Comment