Description
The Prototype design pattern is one of the Creational Design Patterns, which refers to creating a duplicate object, keeping the performance in mind.
- It provides one of the best ways to create an object.
- It is used when the creation of an object directly is costly, like a costly database operation.
For example, an object is to be created after a costly database operation. We can cache the object, returns its clone on the next request, and update the database as and when needed thus reducing database calls.
Implementation in Java
Let's follow the below approach to implement this design pattern in Java.
- Create an abstract class "Shape".
- Create multiple concrete subclasses (like Rectangle, Square, and Circle) that extend the above abstract class.
- Create a class "ShapeCache" that stores the abstract class objects in a Hashtable and returns their clone when requested.
Step 1: Create an abstract class implementing the Cloneable 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;
}
}
Step 2: Create multiple concrete classes, all extending the same abstract class.
Reactangle.java
public class Rectangle extends Shape {
public Rectangle(){
type = "Rectangle";
}
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
Square.java
public class Square extends Shape {
public Square(){
type = "Square";
}
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
Circle.java
public class Circle extends Shape {
public Circle(){
type = "Circle";
}
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
Step 3: Create a class to get concrete classes from the database and store them in a Hashtable.
ShapeCache.java
import java.util.Hashtable;
public class ShapeCache {
private static Hashtable<String, Shape> shapeMap = new Hashtable<String, Shape>();
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: Create a class that uses SuperCache class to get clones of shapes stored in Hashtable.
PrototypePatternDemo.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 clonedShape2 = (Shape) ShapeCache.getShape("2");
System.out.println("Shape : " + clonedShape2.getType());
Shape clonedShape3 = (Shape) ShapeCache.getShape("3");
System.out.println("Shape : " + clonedShape3.getType());
}
}
Step 5: Execute the code to verify the output.
Shape : Circle
Shape : Square
Shape : Rectangle
Overall
We now know about the Prototype design pattern and its implementation.