Prototype Design Pattern - Walking Techie

Blog about Java programming, Design Pattern, and Data Structure.

Thursday, July 14, 2016

Prototype Design Pattern

Prototype pattern is part of creational design pattern that provide best way to clone object from existing object.
Prototype pattern says that cloning of an existing object or instance instead of creating new one and can also customize as per your requirement.

This design pattern is used when creation of new object is costly and resource intensive.For example, In bank account transaction, you would like to make a copy of original object that hold your account information , perform transaction on it, and then replace the original object with customize or modified one. In such case, you would like to use clone() instead of new.

Advantage of Prototype

The main advantage of prototype pattern are:
  • It reduced the need of sub-classing.
  • It hides the complexity of creating the object from client.
  • It speeds up instantiation of large, dynamically loaded classes.

Implementation

We're going to create an abstract class Vehicle implementing Clonable interface and concrete classes extending the Vehicle class. A VehicleCache class is defined as a next step which stores vehicle objects in a Hashtable and returns their clone when requested. PrototypeExample is our demo class is using VehicleCache class to get a Vehicle object.

UML Diagram:
Prototype Design Pattern UML

Step 1

Create abstract class implementing Cloneable interface.
Vehicle.java
public abstract class Vehicle implements Cloneable {
 protected String type;
 private String licenseNo;

 public abstract void printVehicle();

 public String getType() {
  return type;
 }

 public String getLicenseNo() {
  return licenseNo;
 }

 public void setLicenseNo(String licenseNo) {
  this.licenseNo = licenseNo;
 }

 @Override
 protected Object clone() {
  Object clone = null;
  try {
   clone = super.clone();
  } catch (CloneNotSupportedException e) {
   e.printStackTrace();
  }
  return clone;
 }
}

Step 2

Create concrete class extending Vehicle abstract class.
TwoWheeler.java
public class TwoWheeler extends Vehicle {
 public TwoWheeler() {
  type = "Two Wheeler";
 }

 @Override
 public void printVehicle() {
  System.out.println("I am two wheeler.");
 }
}
ThreeWheeler.java
public class ThreeWheeler extends Vehicle {
 public ThreeWheeler() {
  type = "Three Wheeler";
 }

 @Override
 public void printVehicle() {
  System.out.println("I am three wheeler.");
 }
}
FourWheeler.java
public class FourWheeler extends Vehicle {
 public FourWheeler() {
  type = "Four Wheeler";
 }

 @Override
 public void printVehicle() {
  System.out.println("I am four wheeler.");
 }
}

Step 3

Create class that will fetch classes objects from database and store it in Hash Table. Here it is not written logic to fetch instances from database to make code simple.
VehicleCache.java
import java.util.Hashtable;

public class VehicleCache {
 private static Hashtable vehicleMap = new Hashtable();

 public static Vehicle getVehicle(String licenseNo) {
  Vehicle cachedVehicle = vehicleMap.get(licenseNo);
  return (Vehicle) cachedVehicle.clone();
 }

 static public void loadCache() {
  TwoWheeler twoWheeler = new TwoWheeler();
  twoWheeler.setLicenseNo("KA001");
  vehicleMap.put(twoWheeler.getLicenseNo(), twoWheeler);

  ThreeWheeler threeWheeler = new ThreeWheeler();
  threeWheeler.setLicenseNo("MH001");
  vehicleMap.put(threeWheeler.getLicenseNo(), threeWheeler);

  FourWheeler fourWheeler = new FourWheeler();
  fourWheeler.setLicenseNo("BH001");
  vehicleMap.put(fourWheeler.getLicenseNo(), fourWheeler);
 }
}

Step 4

PrototypeExample class is used to clone the object that is stored in hash table.
PrototypeExample.java
public class PrototypeExample {

 public static void main(String[] args) {
  VehicleCache.loadCache();
  Vehicle clonedVehicle = VehicleCache.getVehicle("MH001");
  clonedVehicle.printVehicle(); // I am three wheeler.

  clonedVehicle = VehicleCache.getVehicle("BH001");
  clonedVehicle.printVehicle(); // I am four wheeler.

  clonedVehicle = VehicleCache.getVehicle("KA001");
  clonedVehicle.printVehicle(); // I am two wheeler.
 }
}

Drawback:

The downside of using this design pattern is process of copying the object can be complicated , also Could be difficult to cloning existing classes with internal objects with circular references or which does not support copying.
Each sub-classes of prototype must implement the clone operation.

1 comment :