Prototype Pattern

Prototype Pattern is a creational pattern which refers to creating duplicate object while keeping performance in mind. This pattern involves implementing a prototype interface which tells to create a clone of the current object. This pattern is used when creation of object directly is costly. For example, an object is to be created after a costly database operation. The object can be cached, its clone can be returned on next request for updating database when needed thus reducing database calls.

In the following example an abstract class Shape and its concrete implementations are created. A class ShapeCache is defined as a next step, it stores shape objects in HashMap and returns their clones when requested. Demo class will use ShapeCache class to get Shape object.

Prototype Pattern UML Diagram

Step 1 : Create an abstract class Shape implementing Cloneable interface

public abstract class Shape implements Cloneable {
private String id;
protected String type;

public 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;
}
}

Step 2 : Create concrete classes extending Shape class

public class Rectangle extends Shape {
public Rectangle(){
type = "Rectangle";
}

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

public class Square extends Shape {
public Square(){
type = "Square";
}

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

public class Circle extends Shape {
public Circle(){
type = "Circle";
}

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

Step 3 : Create ShapeCache class to get concrete classes from database and store them in HashMap

public class ShapeCache {
private static Map<String, Shape> shapeMap = new HashMap<>();

public static Shape getShape(String shapeId) {
Shape cachedShape = shapeMap.get(shapeId);
return (Shape)cachedShape.clone();
}

// for each shape run database query and create shape
// shapeMap.put(shapeKey, shape);
// for example, we are adding three shapes
public static void loadCache() {
Circle circle = new Circle();
circle.setId("1");
shapeMap.put(circle.getId(), circle);

Square square = new Square();
square.setId("2");
shapeMap.put(square.getId(), square);

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

Step 4 : Demo class

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

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

Shape clonedShape2 = ShapeCache.getShape("2");
System.out.println("Shape : " + clonedShape2.getType());

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

The output will be :

Shape : Circle
Shape : Square
Shape : Rectangle

Leave a Reply

Your email address will not be published. Required fields are marked *