Prototype Design Pattern in Java

Prototype Design Pattern in Java

In this article, I am going to discuss the Prototype Design Pattern in Java with Examples. Please read our previous article where we discussed Singleton Design Pattern in Java with Real-Time Examples. The Singleton Design Pattern falls under the category of the Creational Design Pattern.

What is a Prototype Design Pattern?

In software development, there are scenarios where creating new objects can be expensive or time-consuming. The Prototype design pattern provides a solution by allowing objects to be created through cloning. By defining a prototype object and creating new instances by cloning it, the pattern eliminates the need for complex instantiation logic. In this article, we will explore the fundamental principles, advantages, and potential disadvantages of the Prototype design pattern, emphasizing its significance in creating objects efficiently and promoting flexibility in object creation.

As per the GOF Definition, Prototype Design Pattern specifies the kind of objects to create using a prototypical instance and creates new objects by copying this prototype.

To simplify the above definition, we can say that, the Prototype Design Pattern gives us a way to create new or cloned objects from the existing object of a class. That means it clones the existing object with its data into a new object. If we do any changes to the cloned object (i.e. new object) then it does not affect the original object.

The Prototype design pattern is a creational pattern that allows objects to be created by cloning existing instances, rather than by using explicit instantiation. It involves the following components:

  • Prototype Interface: Defines the methods that allow cloning of the object. It typically includes a clone method.
  • Concrete Prototypes: Implement the prototype interface and provide the actual cloning logic. These objects are the ones that are cloned to create new instances.
  • Client: Requests the creation of new objects by cloning an existing prototype.
Advantages of Prototype Design Pattern in Java

Some of the advantages of using the prototype pattern are:

  • Reduced Object Creation Overhead: The Prototype pattern eliminates the need for complex object instantiation logic by allowing objects to be created through cloning. This can greatly reduce the overhead associated with creating new objects, especially in cases where object creation is resource-intensive or time-consuming.
  • Customizable Object Creation: The Prototype pattern enables the creation of custom objects by allowing modifications to the cloned instances. Clients can clone a prototype and then customize the resulting object to suit their specific needs. This flexibility promotes code reuse and modularity.
  • Simplified Object Creation Hierarchy: The Prototype pattern simplifies the object creation hierarchy by eliminating the need for subclassing. Instead of creating subclasses for each variation of an object, a client can clone a prototype and customize it as needed. This reduces class proliferation and minimizes the complexity of the object hierarchy.
  • Preservation of Object Relationships: When objects are created through cloning, their relationships and configurations are preserved. This ensures that the cloned objects maintain their associations with other objects, avoiding inconsistencies that may arise from independent object creation.
  • Dynamic Object Creation: The Prototype pattern allows for dynamic object creation at runtime. Clients can clone prototypes based on certain conditions or configurations, enabling the creation of objects on the fly to adapt to changing requirements.
Disadvantages of Prototype Design Pattern in Java

Some of the disadvantages of using the prototype pattern are:

  • Cloning Complexity: Cloning complex objects may be challenging, especially when objects have complex internal states or deep hierarchies. Deep cloning, which involves cloning all the object’s associated objects, can be error-prone and difficult to implement correctly.
  • Deep Copy vs. Shallow Copy: The Prototype pattern raises the issue of whether to perform a deep copy or a shallow copy when cloning objects. A shallow copy may result in objects sharing references to the same underlying data, leading to unintended side effects. A deep copy, on the other hand, can be resource-intensive and may require implementing custom cloning logic for all associated objects.
  • Object Identity: Cloned objects may lose their original object identity, as they are distinct instances from the prototypes. This can impact scenarios where object identity is crucial, such as object comparisons or object equality checks.
  • Impact on Performance: While the Prototype pattern can improve object creation efficiency, the cloning process itself can impact performance. Cloning complex objects may require significant computational resources and can introduce overhead, especially when deep copying is involved.
  • Limited Support for Prototypes with Internal Dependencies: The Prototype pattern may encounter challenges when dealing with prototypes that have internal dependencies or dependencies on external resources. Cloning such prototypes may require additional logic to manage and recreate those dependencies properly.

Note: The Prototype design pattern offers valuable advantages in creating objects efficiently and promoting flexibility in object creation. Its benefits include reduced object creation overhead, customizable object creation, simplified object creation hierarchy, preservation of object relationships, and dynamic object creation. However, developers should be mindful of potential drawbacks, such as cloning complexity, the choice between deep copy and shallow copy, the impact on object identity, performance considerations, and challenges with prototypes having internal dependencies. By carefully evaluating the requirements and considering trade-offs, developers can leverage the Prototype pattern to create objects effectively, promote code reuse, and enhance flexibility in object creation.

Example to Understand Prototype Design Pattern in Java:

The Student class will define a method called “getClone()” that returns a copy of the object. Each Student will implement the “clone” method by creating a new instance of itself and copying its properties to the clone.

When a user wants to create a new student, the application can provide a palette of pre-defined students. The user can select an existing student from the palette and clone it, obtaining an identical student that can be modified independently. This approach saves computational resources and provides a convenient way to create variations of existing shapes.

By using the Prototype pattern, the application can achieve several advantages. Firstly, it reduces the overhead of creating new objects from scratch, as cloning existing objects is often faster and more efficient. Secondly, it allows users to experiment and create variations of students easily by modifying the cloned objects. Additionally, the pattern promotes code reusability, as the same cloning mechanism can be used for different types of objects. This can be described using the following UML:

Prototype Design Pattern in Java with Examples

Implementing Prototype Design Pattern in Java

Step 1: Create a new directory to store all the class files of this project.

Step 2: Open VS Code and create a new project, called prototype.

Step 3: In the project, create a new file called Prototype.java.

Step 4: Add the following lines of code into Prototype.java:

Implementing Prototype Design Pattern in Java

In this file, we have simply added a simple function definition, called getClone(). We have not added any implementation to the function. This is because the Prototype.java file is an interface and not a class. Hence, this function will later be implemented by other classes.

Step 5: In the project, create a new file called Student.java.

Step 6: Add the following lines of code into Student.java:

What is a Prototype Design Pattern?

We have added the following lines of code:

  • On lines 3 and 4, we have added 4 fields for the Student class.
  • On line 7, we have a default constructor. This is a constructor that does not take any arguments.
  • From lines 10 to 16, we have a normal constructor. This is a constructor that takes in all the required arguments to create an object.
  • From lines 18 to 25, we have a function that prints out the contents of the Student object.
  • From lines 27 to 31, we have the implementation of the getClone() function defined in the Prototype.java interface.

Step 7: In the project, create a new file called PrototypeDemo.java. This file will contain the main() function.

Step 8: Add the following lines of code into PrototypeDemo.java:

Advantages of Prototype Design Pattern in Java

In the main() function, we ask the user for some student data. Using this data, we create an object of type Student. Then, we clone the object. We print both objects to demonstrate that the cloning was successful.

Step 9: Compile and execute the application. Ensure compilation is successful. Enter the required data and verify that the cloning was successful:

Disadvantages of Prototype Design Pattern in Java

As can be seen, the cloning was successful. Congratulations! You now know how to implement prototype patterns!

The Complete Example Code
Prototype.java
public interface Prototype
{
    public Prototype getClone();
}
PrototypeDemo.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class PrototypeDemo
{
    public static void main(String[] args) throws IOException
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        System.out.print("Enter student id: ");
        int id = Integer.parseInt(br.readLine());

        System.out.print("Enter student name: ");
        String name = br.readLine();

        System.out.print("Enter student email: ");
        String email = br.readLine();

        System.out.print("Enter student phone number: ");
        String phNo = br.readLine();

        Student s1 = new Student(id, name, email, phNo);

        System.out.println();
        System.out.println("Details of original student: ");
        s1.printStudentInfo();

        //Cloning
        Student s2 = (Student) s1.getClone();
        System.out.println();
        System.out.println("Details of cloned student: ");
        s2.printStudentInfo();
    }
}
Student.java
public class Student implements Prototype
{
    private int id;
    private String name, email, phNo;

    //Default Constructor
    public Student() {}

    //Normal Constructor
    public Student(int id, String name, String email, String phNo)
    {
        this.id = id;
        this.name = name;
        this.email = email;
        this.phNo = phNo;
    }

    public void printStudentInfo()
    {
        System.out.println("Details of student no " + id);
        System.out.println();
        System.out.println("Student Name: " + name);
        System.out.println("Student Email: " + email);
        System.out.println("Student Phone Number: " + phNo);
    }

    @Override
    public Prototype getClone()
    {
        return new Student(id, name, email, phNo);
    }
}
UML Diagram of Prototype Design Pattern

UML Diagram of Prototype Design Pattern

The classes can be described as follows:

  1. PrototypeInterface: This interface should be implemented by a class that wants that to be able to clone itself.
  2. ConcreteClass: This is a class that implements the interface.
  3. DriverClass: This class contains the main() function. It is responsible for handling the simulation of the program.

In the next article, I am going to discuss Builder Design Patterns in Java with Examples. Here, in this article, I try to explain Prototype Design Patterns in Java with Real-Time Examples. I hope you enjoy this Prototype Design Pattern in Java article.

Leave a Reply

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