Prototype Design Pattern

Object Clonning

Prototype Design Pattern

Photo by Lenny Kuhne on Unsplash

Introduction

It is used when we have to copy/clone an existing object.

Consider a scenario where we have an object obtained from a source, and its creation is costly. If we need to make minor modifications to this object for experimentation purposes, sometimes we may need to clone it multiple times.

Problem

A student object typically consists of three variables, but in general, it can be quite heavy with numerous instance variables.

public class Student {
    int age;
    private int rollNumber;
    String name;

    Student(){
    }

    Student(int age, int rollNUmber, String name){
        this.age = age;
        this.rollNumber = rollNumber;
        this.name = name;
    }
}

Cloning logic with in client

public class Main{
    public static void main(String args[]) {
        Student obj = new Student(20, 76, "Chetan");

        //creating clone of obj
        Student cloneObj = new Student();
        cloneObj.name = obj.name;
        cloneObj.age = obj.age;
        cloneObj.rollNumber = obj.rollNumber; //error
    }
}

The issue arises because the cloning logic resides with the client. Therefore, during cloning, it may not be feasible to copy the values of fields with private access modifiers. In some cases, even the getter methods may be private, leaving the client unaware of which fields to copy and which to exclude. To address this challenge, the prototype design pattern is employed.

Solution - Using Prototype Design

UML of Prototype

Explanation

The Prototype design pattern relocates the cloning functionality within the source object, eliminating ambiguity regarding what should be copied and what should not. The benefit of having the clone method within the source object is that it has access to all the elements of the source object, allowing the source object to implement its own cloning logic.

By implementing the prototype interface, the source objects ensure that they possess the clone method, and its naming remains consistent across all objects.

public inteface Prototype{
    Prototype clone();
}
public class Student implements Prototype{
    int age;
    private int rollNumber;
    String name;

    Student(){
    }

    Student(int age, int rollNUmber, String name){
        this.age = age;
        this.rollNumber = rollNumber;
        this.name = name;
    }

    @Override
    public Prototype clone(){
           return new Student(age, rollNumber, name);
    }
}
public class Main{
    public static void main(String args[]){
        Student obj = new Student(20, 75, "Chetan");
        Student cloneObj = (Student) obj.clone();
    }
}