Sunday, February 27, 2011

Singleton pattern

Step 1: Provide a default Private constructor
public class Singleton {

// Note that the constructor is private
private Singleton() {
// Optional Code
}
}
Step 2: Create a Static Method for getting the reference to the Singleton Object
public class Singleton {

private static Singleton instance;
// Note that the constructor is private
private Singleton() {
// Optional Code
}
public static Singleton getInstance() {
if (singletonObject == null) {
singletonObject = new Singleton();
}
return singletonObject;
}
}
We write a public static getter or access method to get the instance of the Singleton Object at runtime. First time the object is created inside this method as it is null. Subsequent calls to this method returns the same object created as the object is globally declared (private) and the hence the same referenced object is returned.

Step 3: Make the Access method Synchronized to prevent Thread Problems.
public static synchronized Singleton getInstance()
It could happen that the access method may be called twice from 2 different classes at the same time and hence more than one object being created. This could violate the design patter principle. In order to prevent the simultaneous invocation of the getter method by 2 threads or classes simultaneously we add the synchronized keyword to the method declaration

Step 4: Override the Object clone method to prevent cloning

We can still be able to create a copy of the Object by cloning it using the Object’s clone method. This can be done as shown below
SingletonObjectDemo clonedObject = (SingletonObjectDemo) obj.clone();
This again violates the Singleton Design Pattern’s objective. So to deal with this we need to override the Object’s clone method which throws a CloneNotSupportedException exception.

public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
The below program shows the final Implementation of Singleton Design Pattern in java, by using all the 4 steps mentioned above.
class Singleton {

private static Singleton singletonObject;
/** A private Constructor prevents any other class from instantiating. */
private Singleton() {
// Optional Code
}
public static synchronized Singleton getInstance() {
if (singletonObject == null) {
singletonObject = new Singleton();
}
return singletonObject;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}

public class SingletonObjectDemo {

public static void main(String args[]) {
// Singleton obj = new Singleton(); //Compilation error not allowed 
Singleton obj = Singleton.getInstance();
// Your Business Logic
System.out.println("Singleton object obtained");
}
}



Another approach
We don’t need to do a lazy initialization of the instance object or to check for null in the get method. We can also make the singleton class final to avoid sub classing that may cause other problems.
public class SingletonClass {

private static Singleton ourInstance = new Singleton();
public static SingletonClass getInstance() {
return singletonObj;
}
private SingletonClass() {
}
}
In Summary, the job of the Singleton class is to enforce the existence of a maximum of one object of the same type at any given time. Depending on your implementation, your class and all of its data might be garbage collected. Hence we must ensure that at any point there must be a live reference to the class when the application is running.

But still there are some issues left.
Protected vs Private Constructor 
protected Singleton() {
// ...
}
The constructor could be made private to prevent others from instantiating 
this class. But this would also make it impossible to create instances of 
Singleton subclasses.
 

No comments:

Post a Comment

Chitika