Sunday, February 17, 2013

Implementation of Singleton pattern with Inheritance and Generics

Some day ago while playing around with Singleton, I had a thought that if it is possible to implement a Singleton class with Generics and Inheritance.
The Singleton classes do mostly same tasks, so I thought maybe I can put the common methods in the parent class using Inheritance.
Usually I create the Singleton object by Lazy Singleton pattern. Here is my parent class AbstractXMLParser:
public abstract class AbstractXMLParser<T> { 
 private static final Map<Class<? extends AbstractXMLParser>, AbstractXMLParser> INSTANCES = new HashMap<>();
 
 public AbstractXMLParser() {
  
 }

 private static class SingletonHolder<T> {    
  private static <T> T getInstance(Class<T> clazz) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
   Constructor<T> constructor = (Constructor<T>) clazz.getDeclaredConstructors()[0];
   constructor.setAccessible(true);   
   return constructor.newInstance(null);
  }
 }
 
 protected static <T extends AbstractXMLParser<T>> T getInstance(Class<T> clazz) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
  if(INSTANCES.containsKey(clazz)) {
   return (T) INSTANCES.get(clazz);
  } else {
   T instance = SingletonHolder.getInstance(clazz);
   INSTANCES.put(clazz, instance);
   return instance;
  }
 }
 
 protected static <T extends AbstractXMLParser<T>> void putInstance(Class<T> clazz, T instance) {
  if(!INSTANCES.containsKey(clazz)) {
   INSTANCES.put(clazz, instance);
  }
 }
}
Here the SingletonHolder inner class is used for Lazy. Note that the instantiation of the new child object has been done through Reflection. And the getInstance method is protected so that it can be accessible from the child classes only. As the Generic types are not visible in runtime so, I had to pass the class name explicitly from the child class's getInstance method to it.
Here is one of the child class ActivityTypeXMLParser:
public class ActivityTypeXMLParser extends AbstractXMLParser<ActivityTypeXMLParser> {

 private ActivityTypeXMLParser() {

 }

 public static ActivityTypeXMLParser getInstance() {
  ActivityTypeXMLParser activityTypeXMLParser = null;

  try {
   activityTypeXMLParser = getInstance(ActivityTypeXMLParser.class);
  } catch (Exception exception) {
  }

  if (activityTypeXMLParser == null) {
   activityTypeXMLParser = new ActivityTypeXMLParser();
   putInstance(ActivityTypeXMLParser.class, activityTypeXMLParser);
  }

  return activityTypeXMLParser;
 }
}
The Map of the parent class is used to store the class name as key the value object to get reference of the object in future call.
I hope you can get an idea how to use Inheritance with Singleton object in Java.