Tuesday, 26 December 2017

Design Patterns | Singleton using enum: Enforce the singleton property with a private constructor or an enum type

A singleton is simply a class that is instantiated exactly once.

Before release 1.5, there were two ways to implement singletons. Both are based on keeping the constructor private and exporting a public static member to provide access to the sole instance.

In one approach, the member is a final field:

/** Singleton with static initialization using a public static final variable. */
public class Singleton {
     public static final Singleton INSTANCEnew Singleton();
     private Singleton() { ... }
}

The private constructor is called only once, to initialize the public static final field Singleton.INSTANCE. Singleton instance will exist once the Singleton class is initialized.

However, a privileged client can invoke the private constructor using reflection by the AccessibleObject.setAccessible method.

/** Singleton with the static factory. */
public class Singleton {
     private static final Singleton INSTANCE = new Singleton();
     private Singleton() { ... }
     public static Singleton getInstance() {
          return INSTANCE;
     }
}

To make a singleton class that is implemented using either of the previous approaches serializable, it is not sufficient merely to add implements Serializable to its declaration.

Each time a serialized instance is deserialized, a new instance will be created. To maintain the singleton guarantee, we need to declare all instance fields transient and provide a readResolve method.

/** readResolve method to preserve singleton property while serialization. */
private Object readResolve() {
     /** Return the one true Singleton and let the garbage collector
      *  take care of the Singleton impersonator.
      */
     return INSTANCE;
}

Singleton using enum
As of release 1.5, there is a third approach to implementing singletons. This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides the guarantee against multiple instantiations, even in the face of sophisticated serialization or reflection attacks.

Enum is thread-safe which helps us to avoid double checking (less code for better results).

While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.

public enum Singleton {
     INSTANCE;
     public void doStuff(){
           System.out.println("Singleton using Enum");
     }
}

/** This is the way to call the Singleton. */
public static void main(String[] args) {
     Singleton.INSTANCE.doStuff();
}


No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...