Open In App

Prototype Design Pattern

The Prototype Design Pattern is a creational pattern that enables the creation of new objects by copying an existing object. Prototype allows us to hide the complexity of making new instances from the client. The concept is to copy an existing object rather than create a new instance from scratch, something that may include costly operations. The existing object acts as a prototype and contains the state of the object.



Suppose a user creates a document with a specific layout, fonts, and styling, and wishes to create similar documents with slight modifications.

Instead of starting from scratch each time, the user can use the Prototype pattern. The original document becomes the prototype, and new documents are created by cloning this prototype. This approach ensures that the new documents inherit the structure and styling of the original document while allowing for customization.



Components of Prototype Design Pattern

The Prototype Design Pattern’s components include the prototype interface or abstract class, concrete prototypes and the client code, and the clone method specifying cloning behavior. These components work together to enable the creation of new objects by copying existing ones.

1. Prototype Interface or Abstract Class

The Prototype Interface or Abstract Class declares the method(s) for cloning an object. It defines the common interface that concrete prototypes must implement, ensuring that all prototypes can be cloned in a consistent manner.

2. Concrete Prototype

The Concrete Prototype is a class that implements the prototype interface or extends the abstract class. It’s the class representing a specific type of object that you want to clone.

3. Client

The Client is the code or module that requests the creation of new objects by interacting with the prototype. It initiates the cloning process without being aware of the concrete classes involved.

4. Clone Method

The Clone Method is declared in the prototype interface or abstract class. It specifies how an object should be copied or cloned. Concrete prototypes implement this method to define their unique cloning behavior. It Describes how the object’s internal state should be duplicated to create a new, independent instance.

Prototype Design Pattern example in Java

Imagine you’re working on a drawing application, and you need to create and manipulate various shapes. Each shape might have different attributes like color or size. Creating a new shape class for every variation becomes cumbersome. Also, dynamically adding or removing shapes during runtime can be challenging.

Let’s understand how Prototype Design Pattern will help to solve this problem:

1. Prototype Interface (Shape):

We define an interface called Shape that acts as the prototype.It declares two methods: clone() for making a copy of itself and draw() for drawing the shape.




// This is like a blueprint for creating shapes.
// It says every shape should be able to clone itself and draw.
public interface Shape {
    Shape clone();  // Make a copy of itself
    void draw();    // Draw the shape
}

2. Concrete Prototype (Circle):

We implement the Shape interface with a concrete class Circle. The Circle class has a private field color and a constructor to set the color when creating a circle. It implements the clone() method to create a copy of itself (a new Circle with the same color).The draw() method is implemented to print a message indicating how the circle is drawn.




// This is a specific shape, a circle, implementing the Shape interface.
// It can create a copy of itself (clone) and draw in its own way.
public class Circle implements Shape {
    private String color;
 
    // When you create a circle, you give it a color.
    public Circle(String color) {
        this.color = color;
    }
 
    // This creates a copy of the circle.
    @Override
    public Shape clone() {
        return new Circle(this.color);
    }
 
    // This is how a circle draws itself.
    @Override
    public void draw() {
        System.out.println("Drawing a " + color + " circle.");
    }
}

3. Client (ShapeClient):

We create a client class, ShapeClient, which will use the prototype to create new shapes. The client has a field shapePrototype representing the prototype it will use. The constructor takes a Shape prototype, and there’s a method createShape() that creates a new shape using the prototype’s clone() method.




// This is like a user of shapes.
// It uses a prototype (a shape) to create new shapes.
public class ShapeClient {
    private Shape shapePrototype;
 
    // When you create a client, you give it a prototype (a shape).
    public ShapeClient(Shape shapePrototype) {
        this.shapePrototype = shapePrototype;
    }
 
    // This method creates a new shape using the prototype.
    public Shape createShape() {
        return shapePrototype.clone();
    }
}

4. Complete code for the above example:

In the main class, PrototypeExample, we create a concrete prototype (circlePrototype) of a red circle. We then create a ShapeClient and provide it with the red circle prototype. The client uses the prototype to create a new shape (redCircle) using the createShape() method. Finally, we draw the newly created red circle using its draw() method.




// Prototype interface
interface Shape {
    Shape clone();  // Make a copy of itself
    void draw();    // Draw the shape
}
 
// Concrete prototype
class Circle implements Shape {
    private String color;
 
    // When you create a circle, you give it a color.
    public Circle(String color) {
        this.color = color;
    }
 
    // This creates a copy of the circle.
    @Override
    public Shape clone() {
        return new Circle(this.color);
    }
 
    // This is how a circle draws itself.
    @Override
    public void draw() {
        System.out.println("Drawing a " + color + " circle.");
    }
}
 
// Client code
class ShapeClient {
    private Shape shapePrototype;
 
    // When you create a client, you give it a prototype (a shape).
    public ShapeClient(Shape shapePrototype) {
        this.shapePrototype = shapePrototype;
    }
 
    // This method creates a new shape using the prototype.
    public Shape createShape() {
        return shapePrototype.clone();
    }
}
 
// Main class
public class PrototypeExample {
    public static void main(String[] args) {
        // Create a concrete prototype (a red circle).
        Shape circlePrototype = new Circle("red");
 
        // Create a client and give it the prototype.
        ShapeClient client = new ShapeClient(circlePrototype);
 
        // Use the prototype to create a new shape (a red circle).
        Shape redCircle = client.createShape();
 
        // Draw the newly created red circle.
        redCircle.draw();
    }
}




Drawing a red circle.

When to use the Prototype Design Pattern 

When not to use the Prototype Design Pattern 


Article Tags :