PROTOTYPE PATTERN

Prototype pattern is one of the Creational Design patterns, so it provides a mechanism of object creation. Prototype pattern is used when the Object creation is a costly affair and requires a lot of time and resources and you have a similar object already existing. So this pattern provides a mechanism to copy the original object to a new object and then modify it according to our needs. This pattern uses java cloning to copy the object.

It would be easy to understand this pattern with an example, suppose we have an Object that loads data from database. Now we need to modify this data in our program multiple times, so it’s not a good idea to create the Object using new keyword and load all the data again from database. So the better approach is to clone the existing object into a new object and then do the data manipulation.

Prototype design pattern mandates that the Object which you are copying should provide the copying feature. It should not be done by any other class. However whether to use shallow or deep copy of the Object properties depends on the requirements and it’s a design decision.

One example of how this can be useful is if an original object is created with a resource such as a data stream that may not be available at the time that a clone of the object is needed. Another example is if the original object creation involves a significant time commitment, such as reading data from a database or over a network.

Normally in Java, if you’d like to use cloning (i.e., the prototype pattern), you can utilize the clone () method and the Cloneable interface. By default, clone () performs a shallow copy. Serializable can be used to simplify deep copying.

However, we can implement our own prototype pattern. To do so, we’ll create a Prototype interface that features a doClone () method.

Below example describes how to design an advanced bike after cloning the basic bike object.

 

package com.myjavablog.prototype;

public class Bike implements Cloneable{

private int gears;
private String bikeType;
private String model;

public Bike() {
gears = 5;
bikeType = "Standard";
model = "BMW";
}

public Bike clone(){
return new Bike();
}

public void makeAdvanced(){
gears = 5;
bikeType = "Advanced";
model = "Jauguar";
}

public int getGears() {
return gears;
}

public String getBikeType() {
return bikeType;
}

public String getModel() {
return model;
}

@Override
public String toString() {
return "Bike{" +
"gears=" + gears +
", bikeType='" + bikeType + '\'' +
", model='" + model + '\'' +
'}';
}
}

Test class –

package com.myjavablog.prototype;

public class PrototypeTest {

public Bike makeJaguar(Bike basicBike){

basicBike.makeAdvanced();
return basicBike;
}
public static void main(String[] args) {

Bike bike = new Bike();
Bike basicBike = bike.clone();
PrototypeTest pt = new PrototypeTest();
Bike advancedBike = pt.makeJaguar(basicBike);

System.out.println("Advanced Bike model:"+ advancedBike.getModel());
System.out.println("Advanced Bike :"+ advancedBike.toString());

}
}

 

Output:

Advanced Bike model:Jauguar
Advanced Bike :Bike{gears=5, bikeType='Advanced', model='Jauguar'}

When to Use:

  • When the classes to instantiate are specified at run-time, for example, by dynamic loading.
  • To avoid building a class hierarchy of factories that parallels the class hierarchy of products.
  • When instances of a class can have one of only a few different combinations of state. It may be more convenient to install a corresponding number of prototypes and clone them rather than instantiating the class manually, each time with the appropriate state.

Usage in JDK:

java.lang.Object#clone ()

Bitnami