Friday, 9 May 2008

Design Patterns Revisited (1); Singletons, how single they are..

Well enough about giving thoughts or chatting about flex, lets get back into important stuff. I decided to give write several posts about design patterns. Either you use or not they are important and make your life easier (and probably increase your salary). Even you really not interested in design patterns, you will face questions about some in interviews or architectural design meetings. So better open up your brain and learn some, nothing wrong to impress few colleagues.
The first pattern I will post is the Singleton Pattern. The mighty gof explains this pattern as; "Ensure a class only has one instance, and provide a global point of access to it.". Simple isn't it, if you need only one instance of a resource mostly because it would be expensive to create and hold new instances, you make sure there is only one unique living instance of that object. Singleton objects are god and if you don't want chaos, conspiracy and fight like Olympian Gods than you must make sure you have only one!
Back to basics how do we construct and instantiate an object.. yes just by using the constructor. Even we don't type the compiler creates a default one for us. So to take control from the compiler we just create a default non-argument constructor and mark it as private. So we ensure no one would ever has access to it, to create a new instance(A). Next we type a public static method so whoever wants to use our object must use that entry point to access(B).
public class SingletonObj {

private final static Singleton instance = new Singleton(); // our unique instance

private Singleton() {} //A

public static Singleton getInstance() { //B

return instance;

}

}

This is the most simplest way to show a singleton. You may also want to use a static initializer so our "instance" will be initialized only when it is first accessed.
public class SingletonObj {

private final static Singleton instance = null;

static {

instance = new Singleton(); // our unique instance

}

private Singleton() {} //A

...

Or you might check if it is initialized in getInstance method.
public class SingletonObj {

private final static Singleton instance = null;

private Singleton() {} //A

public static Singleton getInstance() { //B

if (instance == null){

instance = new Singleton(); // our unique instance

}

return instance;

}

}
All of the examples above works quite same and ensures the current running JVM has only one instance. Most experienced ones are now quite ready to leave a comment on how to hack this design. Ok, you can't just really ensure, but it is a hack and you must be expecting your colleagues not trying to break your design and mess up with resources :)
Since JVM lets us to access even the private methods by reflection and once we get the methods it is possible to change the access rules and create new instances. Here is how to create more instances from a singleton;
public class SingletonHack {

public static void main(String [] args);

Class clazz = Class.forName("SingletonObj"); //we load the class

Constructor[] cons = clazz.getDeclaredConstructors(); //get the constructors

cons[0].setAccessible(true); //change access rights

SingletonObj noMoreSingleton = (SingletonObj) cons[0].newInstance();

//we have brand new instance

}

Actually this is not something new and I'm quite sure most of you already new it. Java is just like having jedi powers. "The dark side of the force is a pathway to many abilities some considered to be unnatural". When you really need, it offers a dark side to make things work but you shouldn't be using that powers and staying on the light side. If you feel you need such a hack you must look back and try to find what did you do wrong and put yourself in Anakin's shoes :)