The prototype design pattern works on the concept of cloning the object, which helps in the creation of complex objects in a very quick time. In other words, the Prototype copies the content and data of one object into a new unique object rather than creating a whole new object from scratch.

In the creational design patterns, the prototype design pattern is used extensively to avoid the cost of object creations. Prototype solves the problem of creating costly and time-consuming objects.

The prototype pattern is achieved by cloning the existing objects mostly with the clone()method. We can also copy the existing objects with the custom logics like a deep copy as per the need.

When to use the prototype design pattern.

  • When the classes that are to be instantiated are specified on runtime.
  • If some objects are required which should be exact same to the existing object.
  • When creating a larger and complex object from scratch. It would be more simple and cost-effective to copy the already existing object.
  • If we need an independent application of how the resources are getting created and composed.

Example and Use-case of Prototype Design Pattern.

Let’s take about a real-world problem and the solution at the same time with the help of Prototype Design Pattern.

Let’s say we have to open an apparel store in which clothes are the main product. Now, the owner decides to open the same outlet of the store at a different location.

This Store setup and opening can be done in two ways, one is to recreate the whole store from scratch and the other is just clone the previous store which is already a fully-established store.

From the above two approaches, the second one is the easiest one and cost-effective as well. In this way, the store can be opened in a very small amount of time and effort.

Implementation of Prototype design.

We will implement the above scenario in Java with the Prototype design pattern.

The below class Apparelstore.java is the Store class which is having two variables storename and the list of the clothes which are present in the store. To fill the store’s product which is clothes in our case, with the data we are using the fetchdata()method, this method is setting the value of clothes with some custom logic.

As mentioned in the above we can use any type of object cloning technique so in the commented block in the below class is for a shallow copy. If we use this code then the object will be cloned with a shallow copy. I have used a Deep copy because it is the suggested technique for the prototype design pattern. The reason behind this is that our cloned object should be independent with the changes in the prototype object(Original Object).

While doing the Deep copy, we have overridden the clone() method and creating a new apparelstore object. After this, in the same object, we are copying the values of Clothes object into the newly created list of clothes. At last, the cloned object is getting returned by the clone() method.

package javadesignpatterns.creational.prototype;

import java.util.ArrayList;
import java.util.List;

public class Apparelstore implements Cloneable {

  private String storename;
  List<Clothes> cloth = new ArrayList<>();

  public String getStorename() {
    return storename;
  }
  public void setStorename(String storename) {
    this.storename = storename;
  }
  public List<Clothes> getCloth() {
    return cloth;
  }
  public void setcloth(List<Clothes> cloth) {
    this.cloth = cloth;
  }

  public void fetchData() {
    for (int i = 0; i < 15; i++) {
      Clothes cloth = new Clothes();
      cloth.setClothsku(i);
      cloth.setClothtype("Type is  " + i);
      getCloth().add(cloth);
    }
  }

  @Override
  public String toString() {
    return "Apparelstore [storename=" + storename + ", cloth=" + cloth + "]";
  }

  /*
   * @Override //shallow copy protected Object clone() throws
   * CloneNotSupportedException { return super.clone(); }
   */

  @Override // Deep copy
  protected Apparelstore clone() throws CloneNotSupportedException {
    Apparelstore appstore = new Apparelstore();

    for (Clothes cl : this.getCloth()) {
      appstore.getCloth().add(cl);
    }

    return appstore;
  }
}

The Clothes.java is the getter and setter class which is getting set in the Apparelstore class as a list. In this scenario, this is basically a product of the store whose information is filled by the above class.

package javadesignpatterns.creational.prototype;

public class Clothes {

  private String clothtype;
  private int clothsku;

  public String getClothtype() {
    return clothtype;
  }
  public void setClothtype(String clothtype) {
    this.clothtype = clothtype;
  }
  public int getClothsku() {
    return clothsku;
  }
  public void setClothsku(int clothsku) {
    this.clothsku = clothsku;
  }
  @Override
  public String toString() {
    return "Clothes [clothtype=" + clothtype + ", clothsku=" + clothsku + "]";
  }
}

The PrototypeMain.java is our main class in which we are trying to copy the object from the prototype object. At first, we have created a new store and set the name of the store. fetchData()will set the data into the clothes list the prototype store will be created.

Again, Now we are trying to create the other store which will be a copy of the prototype store. We have just called the clone() which we have created in the Apparelstore.java class. This will create a completely new outlet of the store with the same clothes that were available in the prototype store.

package javadesignpatterns.creational.prototype;

public class PrototypeMain {

  public static void main(String[] args) throws Exception {
    Apparelstore appstore = new Apparelstore();
    appstore.setStorename("Prototype Store");
    appstore.fetchData();
    System.out.println(appstore);
    Apparelstore duplicatedappstore = appstore.clone();
    duplicatedappstore.setStorename("Cloned Store");
    System.out.println(duplicatedappstore);
  }
}

Advantages of Prototype Design pattern

  • Easy object construction in less time can be done.
  • By implementing above we can reduce the sub-classing techniques
  • We can clone the objects from the clone method or our own custom logic.
  • It simplifies the requirement where multiple objects of the same type can have the same data.
  • We can modify the objects on runtime.

Disadvantages of Prototype Design pattern

  • Managing the cloned objects will be tough.
  • Not good for the large-scale applications
  • It will be tough to choose between the Deep vs shallow copy.
  • Mostly, it is not clear when to use this pattern.

I hope to have given you a good inside to Prototype design pattern. Please share your feedback in the comments below. You can also download the code example from GitHub.

By |Last Updated: May 9th, 2020|Categories: Java™|