It is used in scenarios where application needs to create a number of instances of a class, which has almost same state or differs very little.

When we use it ?

The main objective of this pattern is to:

  • avoid subclasses of an object creator in the client application, like the abstract factory pattern does.
  • avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it is prohibitively expensive for a given application.

We use the prototype pattern on applications that will require instances of an object which creation process is costly, for instance after a database operation. We can cache the object, returns its clone on next request and update the database as and when needed thus reducing database calls.

An easy application example,

First, we create an abstract class implementing Clonable interface.

Shape.java

public abstract class Shape implements Cloneable{
   
   private String id;
   protected String type;
   
   abstract void draw();
   
   public String getType(){
      return type;
   }
   
   public String getId(){
      return id;
   }
   
   public void setId(String id){
      this.id = id;
   }
   
   public Object clone(){
      Object clone =null;
      
      try{
         clone =super.clone();
         
      }catch(CloneNotSupportedException e){
         e.printStackTrace();
      }
      
      return clone;
   }
}

We create concrete classes extending the above class.

Rectangle.java

public class Rectangle extends Shape{

   public Rectangle(){
     type ="Rectangle";
   }

   @Override
   public void draw(){
      System.out.println("Inside Rectangle::draw() method.");
   }
}

Circle.java

public class Circle extends Shape{

   public Circle(){
     type ="Circle";
   }

   @Override
   public void draw(){
      System.out.println("Inside Circle::draw() method.");
   }
}

Next, we create a class to get concrete classes from database and store them in an structure, for instance in a Hashtable.

ShapeCache.java

import java.util.Hashtable;

public class ShapeCache {
	
   private static Hashtable<String,Shape> shapeMap=newHashtable<String,Shape>();

   public static Shape getShape(String shapeId){
      Shape cachedShape = shapeMap.get(shapeId);
      return(Shape) cachedShape.clone();
   } 
   
   /** this method load the objects from any data store **/
   public static void loadCache(){
      Circle circle=newCircle();
      circle.setId("1");
      shapeMap.put(circle.getId(),circle);

      Rectangle rectangle =newRectangle();
      rectangle.setId("3");
      shapeMap.put(rectangle.getId(), rectangle);
   }
}

PrototypePatternShape uses ShapeCache class to get clones of shapes stored in a Hashtable.

PrototypePatternShape.java

public class PrototypePatternDemo{
   public static void main(String[] args){
      ShapeCache.loadCache();

      Shape clonedShape =(Shape)ShapeCache.getShape("1");
      System.out.println("Shape : "+ clonedShape.getType()); 	

      Shape clonedShape3 =(Shape)ShapeCache.getShape("3");
      System.out.println("Shape : "+ clonedShape3.getType());		
   }
}

The output is as follows.

Shape : Circle
Shape : Rectangle

 

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Pin It

Add comment


Security code
Refresh