Design pattern notes for technical interviews
Here's my expanding lists of notes for Design Patterns, I'm pretty familiar with them so this may be on the more advanced side of things. Anyway, this is still a work in progress...
Singleton
If you're a Java dev you're going to be asked this question time and time again. Here's some notes on the more advanced issues you might encounter.
Notes in from this great Java World article
My runnable examples from the article
Basic singleton, not thread safe, race condition at initalizaiton.
public class SimpleSingleton { private static SimpleSingleton instance = null; private void SimpleSingleton() { //just to protect } public static SimpleSingleton getInstance() { if (instance == null) { instance = new SimpleSingleton(); } return instance; } }
Just syncronize getInstance and it's thread safe, this is slower.
public class SimpleSingletonThreadSafe { private static SimpleSingletonThreadSafe instance = null; private void SimpleSingletonThreadSafe() { //just to protect } public static synchronized SimpleSingletonThreadSafe getInstance() { if (instance == null) { instance = new SimpleSingletonThreadSafe(); } return instance; } }
Java guarantees static members are created when they are first accessed. Use this to build another thread safe singleton.
public class SimpleSingletonStatic { public final static SimpleSingletonStatic INSTANCE = new SimpleSingletonStatic(); private SimpleSingletonStatic() { // So we can't init } public static void main(String args[]) { SimpleSingletonStatic singleton = SimpleSingletonStatic.INSTANCE; //singleton.getName(); //singleton.setName(); } }
Use reflection to load up classes, this way we can create a singleton out of any class pulled from this registry loader.
public class SingletonRegistry { public static SingletonRegistry REGISTRY = new SingletonRegistry(); private static HashMap map = new HashMap(); protected SingletonRegistry() { // Exists to defeat instantiation } //use like... SingletonRegistry.REGISTRY.getInstance("asdf") public static synchronized Object getInstance(String classname) { Object singleton = map.get(classname); if(singleton != null) { return singleton; } try { singleton = Class.forName(classname).newInstance(); System.out.println("created singleton: " + singleton); } catch(ClassNotFoundException cnf) { System.out.println("Couldn't find class " + classname); } catch(InstantiationException ie) { System.out.println("Couldn't instantiate an object of type " + classname); } catch(IllegalAccessException ia) { System.out.println("Couldn't access class " + classname); } map.put(classname, singleton); return singleton; } }
One JVM can have many classloaders (like a application server trying to separate the app running on it). Ensure that there is only one instance of each singleton per classloader.
public class Singleton { public static Singleton INSTANCE = new Singleton(); private static Class getClass(String classname) throws ClassNotFoundException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if(classLoader == null) { classLoader = Singleton.class.getClassLoader(); } return (classLoader.loadClass(classname)); } public static void main(String args[]) throws ClassNotFoundException { Class dog = Singleton.INSTANCE.getClass("net.largepixels.designpatterns.singleton.classloaderProtect.Dog"); System.out.println(dog.getDeclaredFields()); } }