Sunday 22 June 2014

Prototype Design Pattern



This is a part of Creational pattern, which helps to create objects as per request. This pattern uses philosophy of cloning to create objects, and we know that two way of cloning is possible, one is shallow cloning, and another is deep cloning. Behavior of both cloning types is different so choose wisely that which type of cloning you need.
You can learn more about cloning here:
When to use Prototype pattern?
               i) If creation of object is complex or costly
               If addition or removal of objects are expected on runtime
               If client should be unaware of the object creation
               If similar object is required as the existing one

One scenario where prototype pattern is used?
               When creating a bank application, and we know that bank transactions need expensive database queries. Transactions would be linked with bank account which may be an individual or group and having their profile with bank. So in this case once the actual object would be created (exactly single object), it may be required further in number of places, so prototype can be used to get the copy of object and finally the modified object can replace the old object.

Example:-
PrototypeClient.java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class PrototypeClient {
               public static void main( String[] args ) {
                              Shoes xyz = Factory.makeObject("Sport");
                              xyz.wear();
               }
}


Shoes.java
abstract class Shoes implements Serializable, Cloneable{  
               private static final long serialVersionUID = -1937047519230746677L;
               abstract void wear();
               public Object shallowCloning() throws CloneNotSupportedException    {
                              return this.clone();
               }
               public Shoes deepCloning() throws IOException, ClassNotFoundException{
                              //Serialization of object
                              ByteArrayOutputStream bos = new ByteArrayOutputStream();
                              ObjectOutputStream out = new ObjectOutputStream(bos);
                              out.writeObject(this);
                              //De-serialization of object
                              ByteArrayInputStream bis = new   ByteArrayInputStream(bos.toByteArray());
                              ObjectInputStream in = new ObjectInputStream(bis);
                              Shoes clonedShoes = (Shoes) in.readObject();
                              return clonedShoes;
               }
}

SportShoes.java
class SportShoes extends Shoes {
               private static final long serialVersionUID = 440347043243434494L;
               public String toString() {
                              return "SportShoes";
               }
               @Override
               public void wear() {
                              //some SportShoes specific code to wear
                              System.out.println("I am wearing " + toString());
               }
}

CasualShoes.java
class CasualShoes extends Shoes {
               private static final long serialVersionUID = -6493171299609719559L;
               public String toString() {
                              return "CasualShoes";
               }
               @Override
               public void wear() {
                              //some CasualShoes specific code to wear
                              System.out.println("I am wearing " + toString());
               }
}

FormalShoes.java
class FormalShoes extends Shoes {
               private static final long serialVersionUID = -5670125744755511170L;
               public String toString() {
                              return "FormalShoes";
               }
               @Override
               public void wear() {
                              //some FormalShoes specific code to wear
                              System.out.println("I am wearing " + toString());
               }
}
Factory.java
class Factory {
               private static Map<String, Object> prototypes = new HashMap<String, Object>();
               static {
                              prototypes.put( "Sport",   new SportShoes() );
                              prototypes.put( "Casual",  new CasualShoes() );
                              prototypes.put( "Formal", new FormalShoes() );
               }
               public static Shoes makeObject(String shoesType) {
                              Shoes shoes = (Shoes)prototypes.get(shoesType);
                              //deep cloning (using in-memory)
                              try {
                                             Shoes deepClonedShoes = shoes.deepCloning();
                                             System.out.println("Deep-Cloned Shoes ========== "+deepClonedShoes);
                              } catch (IOException e) {
                                             e.printStackTrace();
                              } catch (ClassNotFoundException e) {
                                             e.printStackTrace();
                              }
                              //Shallow cloning
                              Shoes shallowClonedShoes = null;
                              try {
                                             shallowClonedShoes = (Shoes) shoes.shallowCloning();
                              } catch (CloneNotSupportedException e) {
                                             e.printStackTrace();
                              }
                              System.out.println("Shallow-Cloned Shoes ========== " +shallowClonedShoes );
                              return shallowClonedShoes;
               }
}

Output:
 Deep-Cloned Shoes ========== SportShoes
Shallow-Cloned Shoes ========== SportShoes
I am wearing SportShoes

No comments:

Post a Comment