Sunday, 30 May 2010

Example program for singleton design pattern

//PrinterDemo class has implemented Cloneable, Serializable ( Serialization of Objects)
package com.raj;

import java.io.Serializable;

public class PrinterDemo implements Cloneable,Serializable
{
//if your super class has implemented this method, it will be automatically visible
@Override
public Object clone() throws CloneNotSupportedException
{
return(super.clone());
}

}

//Printer.java
//Printer class implementing Singleton Design Pattern
package com.raj;

public class Printer extends PrinterDemo 
{
private static Printer p=null;
//1st time true, 2nd time-false, Used for Reflection API Proof
//and Multi-Thread double check
private static boolean isNew=true;
//private constructor
private Printer()
{
//to prevent Reflection API creating Multiple objects
if(isNew)
//this sleep is added to prove MultiThread can create multiple Objects if they are not synchronized
try
{
Thread.sleep(5000);
}
catch(Exception e)
{
}
isNew=false;
System.out.println("Printer()");
}//if
else
{
throw new InstantiationError("Cannot create Multiple Object");
}//end of else
 }//end of constructor
public void print(String data)
{
System.out.println("Printer.print()..printing:"+data);
}
public synchronized final static Printer getInstance()
{
if(p==null)
{
p=new Printer();
}//end of if
return(p);
}//end of getInstance()
/*
* if you want to use synchronized block
* public static final Printer getInstance()
* {
*  if(p==null)
*  {
*   synchronized(Printer.class)
*   {
*    p=new Printer();
*    }
*   }
*   return(p);
*   }//end of getInstance()
* * 
*/
//Any Cloning process, then it will return same old object
public Object clone() throws CloneNotSupportedException
{
//throw new CloneNotSupportedException();
return(p);
}
//Any Deserialization Process will give you the same Object
protected Object readResolve()
{
System.out.println("readResolve()");
return(p);
}
}

//TestClient.java
package com.raj;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;

class MyThread implements Runnable
{
public void run()
{
System.out.println("MyThread.run():"+Thread.currentThread().getName());
Printer p=Printer.getInstance();
p.print("Print 1");
System.out.println("HashCode"+p.hashCode());
}
}
public class TestClient 
{
public static void main(String args[]) throws Exception
{
System.out.println("creating Printer class object Normally");
Printer p1=Printer.getInstance();
Printer p2=Printer.getInstance();
Printer p3=Printer.getInstance();
p1.print("Print 1");
p2.print("Print 1");
p3.print("Print 1");
System.out.println("HashCode");
System.out.println("p1 :"+p1.hashCode());
System.out.println("p2 :"+p2.hashCode());
System.out.println("p3 :"+p3.hashCode());
System.out.println("Trying cloning Object");
//Remove Printer.clone(), it will create different objects
Printer p4=Printer.getInstance();
Printer p5=Printer.getInstance();
Printer p6=Printer.getInstance();
p4.print("Print 4");
p5.print("Print 5");
p6.print("Print 6");
System.out.println("HashCode");
System.out.println("p4 :"+p4.hashCode());
System.out.println("p5 :"+p5.hashCode());
System.out.println("p6 :"+p6.hashCode());
//de-serialization of objects
System.out.println("creating singleton object using Serialization and Deserialization");
//Remove Printer.readResolve() and it will create multiple object upon Deserialization
//please refer to   Reading Data from a File using FileInputStream if you have any doubts about //filesInputstream
FileOutputStream fos=new FileOutputStream("d:/printer.txt");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(p1);
oos.close();
System.out.println("Object is serialized");
System.out.println("Now Deserialzing");
FileInputStream fis=new FileInputStream("d/printer.txt");
ObjectInputStream ois=new ObjectInputStream(fis);
Printer p7=(Printer)ois.readObject();
ois.close();
ois=new ObjectInputStream(new FileInputStream("d:/printer.txt"));
   Printer p8=(Printer)ois.readObject();
   
   p7.print("Print 7");
   p8.print("Print 8");
   
   System.out.println("HasCode;");
   System.out.println("p7 :"+p4.hashCode());
   System.out.println("p8 :"+p5.hashCode());
   
   System.out.println("Creating printer class Object using Multple Threads");
   
   //remove synchronized modifier (keyword) from getInstance(), you will see 2 different object
   Thread th1=new Thread(new MyThread());
   th1.start();
   
   Thread th2=new Thread(new MyThread());
   th2.start();
       
   System.out.println("creating Printer class object using Reflectio API");
   //Remove boolean check logic from printer constructor and it will create create different objects
   Class c=Class.forName("Printer");
   Constructor conList[]=c.getDeclaredConstructors();
   conList[0].setAccessible(true);//makes the constructor accessible
   
   Constructor c1=conList[0];
   //will create 3 new objects
   Printer p9=(Printer)c1.newInstance();
   Printer p10=(Printer)c1.newInstance();
   Printer p11=(Printer)c1.newInstance();
   
   p9.print("Print 9");
   p10.print("Print 10");
   p11.print("Print 11");
   
   System.out.println("p9 :"+p9.hashCode());
   System.out.println("p10 :"+p10.hashCode());
   System.out.println("p11 :"+p11.hashCode());
   
}
}
/*
Output: (some bugs are there, to be fixed)

HashCode
p4 :9634993
p5 :9634993
p6 :9634993
creating singleton object using Serialization and Deserialization
Object is serialized
Now Deserialzing
Exception in thread "main" java.io.FileNotFoundException: d\printer.txt (The system cannot find the path specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at java.io.FileInputStream.<init>(FileInputStream.java:66)
at com.raj.TestClient.main(TestClient.java:63)


*/
Singleton Design pattern
Example applications for Singleton java class

Example applications for Singleton java class

Example applications for Singleton java class
1. Example program for singleton design pattern

Saturday, 29 May 2010

Singleton Design pattern

Singleton Design pattern:

Singleton design pattern is a java class, which allows us to create only one object per  JVM..


  • Sometimes it is important to have only one object for a class.
  • Generally Singletons are used for centralized management of internal or external resources and they provide a global point of access to themselves.
  • The singleton java class is used to encapsulate the creation of an object  in order to maintain control over it. This is nothing but a late instantiation (the instantiation of object can be delayed until it is actually needed. This is especially beneficial if the constructor needs to perform a costly operation, such as accessing a remote database.
Note:
  • When we want to create only one object or when the container is creating only one object even though that class allows to create multiple objects then that java class is not singleton java class.
  • According to this, then a java class of servlet program is not singleton java class. It is a normal java class for which Servlet container creates only one object
Where we have to use(Applications of Singleton):

  • It should be used when there must be exactly one object (instance) of a class, and when it must be accessible to clients from a global access point. (So provide a global point of access to the object)
  • if multiple applications of a project that are running from a single JVM wants to work with objects of java class having same data then it is recommended to make that java class as singleton java class. So that only one object will be allowed to create for that class and we can use that object for multiple tiles in multiple applications.
Example: 
  1. in Log4j (Logging for Java) environment tool, the Logger class is given as singleton java class
  2. java.lang.Runtime class is singleton java class
  3. java.awt.Desktop is singleton java class
Rules for Singleton Design Pattern:

  1. Declare a private static reference variable to hold current class Object. This reference variable will hold null only for the first time, after then it will refer to the object forever (till JVM terminates). We will initialize this reference using static factory method as discussed in step 3.
Example:
class Printer
{
   private static Printer p=null;
}
2.  Declare all the constructor as private so that its object can not be created from outside of the class using new keyword.

Example:
class Printer
{
 private static Printer p=null;
private Printer()
{
 System.out.println("Printer()");
}
}
3. Develop a static final factory method, which will return a new object only for the first time and the same object will be returned then after. Since we have only private constructor, we cannot use new keyword from outside of the program, we must declare this method as static, so that it can be accessed directly using Class Name. Declare this final so that the child class will have no option to override and change the default behaviour.

Ex:
 public static final Printer new Instance()
 {
    if(p==null)
    {
      p=new Printer();
    }
    return(p);
 }

4. Make Singleton class Reflection API proof /
we know that Reflection API can access the private variables, methods and constructors of the class, hence even if your constructor is private, we can still create the object of that class. To prevent this declare an instance boolean variable initiallialy holding true. Change its value to false, immediately when constructor is called for the first time. Then after when even the constructor is called for 2nd time, it should throw SomeException saying object can not be created for multiple times.
this approach also removes the Double checking problem in case of Multiple thread trying to create object at the same time.

Ex:
public class Printer
{
 private static boolean isNew=true;//1st time true, 2nd time is false, used for Reflection API proof, and multi-                                                    //Thread double check
 private Printer()
 {
   //to prevent Reflection API creating Multiple objects
   isNew=false;
   System.out.println("Printer()");
 }
  else
 {
   throw new InstanceiationError("Can not create Multiple objects");
  }
 }
}

5. Make Factory Method Thread safety, so that Only one object is created even if more than one thread tries to call this method simultaneously. Declare the whole method as synchronized method, or use synchronized block.
public synchronized final static Printer getInstance()
{
 if(p==null)
  p=new Printer();
 return(p);
}
 (or)
public static final Printer getInstance()
 {
   if(p==null) //1st null check
   {
     synchronized(Printer.class)
     {
       if(p==null)//2nd null check
       {
         p=new Printer();
       }
     }
  }
  return(p);
}
Note: In case of synchronized block we have done null check for 2 times. Lets find out why:

Assume 2 threads are calling getInstance() simultaneously and there is no 2nd Null check. Thread1 calls getInstance() first, finds p=null for the 1st time, then gets lock on Printer class. Once it gets the lock it enter synchronized block and starts creating printer class object by calling the constructor for the 1st time. Assume the object creation will take 10 seconds, due to lots of background activities. At the same time Thread2 calls getInstance(). It also finds p=null (As object is not created ye) enters the first Null check. It will then try to acquire lock on Pritner class, But since its alrady been acquired by Thread1, Thread2 has to wait for 10 sec outside of synchronized block. After 10 second Thread1 will complete the object creation process and then releases the lock. Once lock is released Thread2 will acquire the lock and enters inside the Synchronized block. Now if we don't have 2nd null check, the Object will be created for 2nd times as well, which is what we don't want. Hence we have two level have used the two of null checks here.

Note: If you have used the Reflection PRoof logic, then no need to worry about the 2nd null check. Because when you call the constructor for 2nd time, it will throw InstantiationError.

6. Prevent Singleton object from De-serialization. If you need singleton object to send across the network, singleton class must implement serialization interface. But problem with this approach is we can de-serialize it for N number of times, and each deseriliazation process will create a brand new object , which will violate the singleton Design pattern.

In order to prevent multiple object creation during deserialization process, override readResolve() and return the same object. readResolve method is called internally in the process of deserialization. It is used to replace de-serialized ojbect by choice.

public class Printer
{
 private static Printer p=null;
 private Printer()
{
..
 }
 //any deserialization process will give the same object
  protected Object readResolve()
  {
    System.out.println("readResolve()");
  return(p);
 }
}
Note: ignore this process if class does not implement serializable interface directly or indirectly. Indirectly means the super class or super interfaces has not implmented/extended Serializable interface.

7. Prevent Singleton Object being Cloning. If your class is direct child of Object class, then I will suggest not to implement Cloneable Interface, as there is no meaning of cloning the singleton object to produce duplicate objects out of it. Both are opposite to each other. However if class is the child of some other class or interface and that class or interface has implemented/extended Cloneable interface, then it is possible that somebody may clone your singleton class thereby creating many objects. We should prevent this as well .

Override clone() in your singleton class and return the same old object. You may also throw CloneNotSupportedException.

public class Printer
{
 private static Printer p=null;
 private Printer()
 {
   ...
  }
//any cloning process will return you the same old object
 public Object clone() throws CloneNotSupportedException
 {
   //throw new CloneNotSupportedException();
   return(p);//If you want to return the same old object
 }
}

8. Inspite of all the above efforts, There is still a loop hole "The boss Reflection API ". Using refection API, the programmer can get access to private constructors, variables, and methods, We have to prevent this for Singleton Design Pattern.

Declare a static instance variable to count how many times the object. For the first time when ever constructor is called, increment the count to 1. Next time when constructor is called, check if the value is one or not. If yes, throw InstantiationError.
The below code makes singleton java class as Thread safety without using Reflection API proof code and synchronization concepts.
9. Use Static block or static defination. If you feel you don't want to use synchronized method or block but still want to achieve singleton behavior. you can use static block or static definition to initialize the singleton java class object as follows.

public class Printer
{
private static Printer p=new Printer();
 /* or
 private static Printer p=null;
 static
 {
   p=new Printer();
  }
*/
 
//private constructor
private Printer()
{
System.out.println("Printer()");
}
public void print(String data)
{
System.out.println("Printer.print()..printing:"+data);
}
public final static Printer getInstance()
{
return(p);
}//end of getInstance()
Note: This approach will create the Object even if you don't need them urgently (during class loading). This is not used so frequently in the industry.

Example program for employee details by using Factory method

Example program on Factory method
//by using Static factory method and instance factory method
package com.raj;

public class Employee {
int empId;
String empName;
float empSalary;

//private zero argument constructor
private Employee()
{
System.out.println("Default constructor");
}
//static factory method
public static Employee createNewEmployee(int empId,String empName)
{
//use Class.forName ()
Employee emp=new Employee();
emp.empId=empId;
emp.empSalary=6000;//default salary of new employee
emp.empName=empName;
return(emp);
} //end of static factory method
//instance factory method
//To increment salary, we need existing employee object
public Employee incrementSalary(float hike)
{
Employee emp=new Employee();
emp.empSalary=this.empSalary*(1+hike);//20% hike
//copy all the necessary properties
emp.empId=this.empId;
emp.empName=this.empName;
return(emp);
}
public String toString()
{
return("EmpDetails="+empId+":"+empName+":"+empSalary);
}

} //end of Employee class

package com.raj;

public class TestClient {
public static void main(String args[]) throws Exception
{
Employee emp1=Employee.createNewEmployee(1001, "Rama");
//emp1 calls toString()method internally
System.out.println(emp1);

Employee emp2=emp1.incrementSalary(0.20f);
System.out.println("With Hike"+emp2);
}//main

}//end of TestClient class
/* output
 * Default constructor
EmpDetails=1001:Rama:6000.0
Default constructor
With HikeEmpDetails=1001:Rama:7200.0005

 */
*/
Factory Method

More Example programs on Factory Method

Factory Method

Factory Method or Simple Factory Method


  • The method is capable of creating and returning either its own class object or some other class object is called Factory Method.
Advantages:

  • to create object of java class out side the class when class is having only private constructors
  • to centralise object creation process in single method and to apply restriction number of object creation
  • to create new object based on existing object and its data
  • to develop immutable java class
Rules to use Factory method


  • this method should return one or other class object. If return type is abstract class or interface, the method must return one or other implementation of that abstract class or interface
  • The Factory method should not return primitive data type or void
  • method defination should have logic of creating and returning a class object 
  • factory method can be a static factory method or an instance factory method.
  •  

Types of Factory Method

Static factory methods
Instance factory method

Static factory methods:


  • it is useful to create an object of a java class outside of that class when that class is having only private constructor or you want to create a new object based on current status of the existing object.
Example:
  1.   Class c=Class.forName(...);// new object
  2. Thread t=Thread.currentThread();//based on Current Status
  3. Toolkit tk=Toolkit.getDefaultToolkit();//new object
java class have Factory methods even though that class is having public constructors.

Instance factory method


  • it is useful to create a new object for java class by using existing object and its data.
Ex:
for pre defined instance factory method is:

String s1="Good morning";//existing object
String s2=s1.substring(3,7);//new object i.e: it gives come

Class c=Class.forName("Demo");//static factory method returning Class object
Object ob=c.newInstance();//non-static factory method returning Demo class object wrapped inside Object class object

Example program on Factory method
//by using Static factory method and instance factory method
package com.raj;

public class Employee {
int empId;
String empName;
float empSalary;

//private zero argument constructor
private Employee()
{
System.out.println("Default constructor");
}
//static factory method
public static Employee createNewEmployee(int empId,String empName)
{
//use Class.forName ()
Employee emp=new Employee();
emp.empId=empId;
emp.empSalary=6000;//default salary of new employee
emp.empName=empName;
return(emp);
} //end of static factory method
//instance factory method
//To increment salary, we need existing employee object
public Employee incrementSalary(float hike)
{
Employee emp=new Employee();
emp.empSalary=this.empSalary*(1+hike);//20% hike
//copy all the necessary properties
emp.empId=this.empId;
emp.empName=this.empName;
return(emp);
}
public String toString()
{
return("EmpDetails="+empId+":"+empName+":"+empSalary);
}

} //end of Employee class

package com.raj;

public class TestClient {
public static void main(String args[]) throws Exception
{
Employee emp1=Employee.createNewEmployee(1001, "Rama");
//emp1 calls toString()method internally
System.out.println(emp1);

Employee emp2=emp1.incrementSalary(0.20f);
System.out.println("With Hike"+emp2);
}//main

}//end of TestClient class
/* output
 * Default constructor
EmpDetails=1001:Rama:6000.0
Default constructor
With HikeEmpDetails=1001:Rama:7200.0005

 */
*/