Friday, May 4, 2012

Singleton Pattern

Introduction

Singleton design pattern is the most simplest design pattern among all the other design patterns. This pattern gives you a single instance for you throughout the system or program.

Example

Suppose you have a class , say Singleton, and you want to have only one instance throughout your program. Is it clear? Just one instance. No more than one instance. So in this case you are aware to create only one instance throughout the program. Ok, in this case you have to use singleton design pattern. Let's see how it should be done.

Singleton.java

package com.blog.patterns.singleton;

/**
 * @author uditha
 */
public final class Singleton {

 private static final Singleton INSTANCE = new Singleton();
 
 private Singleton() {
  System.out.println("Singleton instance is created.");
 }
 
 public static Singleton getInstance() {
  return INSTANCE;
 }
 
 @Override
 public Object clone() throws CloneNotSupportedException {
  throw new CloneNotSupportedException("Clone is prohibited.");
 }
 
}

Discussion

In this class you can see the constructor is private.
 private Singleton() {
  System.out.println("Singleton instance is created.");
 }
That means constructor is not visible to out side world. It is the tricky part of this pattern to prevent instance creation from out side the world. And another thing is you can see the field name INSTANCE is static and final.
 private static final Singleton INSTANCE = new Singleton();
As you already know static fields are created at class loading time and share the static fields with the instances created from its class. So that means static fields will never be created at the time it create instances. In this case the constructor is private. There is no way to create instances from out side the word. But you can see INSTANCE field was assigned a object of Singleton class. That means there is one instance of Singleton , created by itself. So making this field static, it will take care of sharing a single INSTANCE field with other instances of Singleton class (in any case). But according to above example it is not possible to create more than one instance.

Then next question is why this field is final. As you might know final fields can be assigned only once. So making that field final, guaranteed we use the same instance assigned at class loading time. In other words assigned object will not be changed.

If this field is private then how can access this INSTANCE variable from out side of this class. That is why we should provide a static method to access INSTANCE variable as follows.

 public static Singleton getInstance() {
  return INSTANCE;
 }

Advanced

  • You might have known about the java clone method of Object class. So using this method we can create a copy of any object. Why I mention this method because if we want to use singleton design pattern we should aware of creating clones of singleton class because we need only one object. So as a best practice we should use following code snippet to your class.

 @Override
 public Object clone() throws CloneNotSupportedException {
  throw new CloneNotSupportedException("Clone is prohibited.");
 }

  • When creating a singleton class you should check about the thread safety of that class. Above example is thread safety one.
  • Next fact is avoiding sub classes. So you can do it this easily making the singleton class final.
  • Using == operator you can check getInstance()  method provide references that refers to same object or not.
package com.blog.patterns.singleton;

/**
 * @author uditha
 */
public class Main {
 
 public static void main(String[] args) {
  System.out.println("First instance creation begin");
  Singleton firstInstance = Singleton.getInstance();
  System.out.println("First instance creation end");
  System.out.println("Second instance creation begin");
  Singleton secondInstance = Singleton.getInstance();
  System.out.println("Second instance creation end");
  if (firstInstance == secondInstance) {
   System.out.println("Those instances refer to same object.");
  } else {
   System.out.println("Two different objects.");
  }
 }

}

Output
First instance creation begin
Singleton instance is created.
First instance creation end
Second instance creation begin
Second instance creation end
Those instances refer to same object.

No comments:

Post a Comment