Prototype pattern

Prototype pattern overview


It is one of the creational design patterns in Java as it is used to create an object.

This pattern helps in creating objects based on the template of an existing object using cloning.

Instead of creating an object from scratch each and every time, we can create the copies of original object.

We can use the copied object and modify it as and when required.

This pattern is already used by java in Cloneable interface.

Cloneable interface acts as a marker interface to indicate what objects are eligible for cloning

Object class has already provided a definition for clone () method and any class in java can use it or it can override this clone () method to provide its own implementation.

The prototype design pattern mandates that the class(whose objects needs to be created again and again) should provide the copying feature.
It should not be done by an external utility class.

While implementing this pattern, we may use clone method provided by Java,
But decide based on requirement whether we need to use shallow cloning or deep cloning and implement clone() method of your own accordingly.

Prototype_pattern

Let’s see the Pattern implementation


Step 1
First define a prototype interface by declaring a clone method
This is actually called as “Prototype”

Step 2
Define the multiple concrete prototype classes which implements the “Prototype” interface and define the clone() method as per the need

Step 3
Add all the prototypes to a prototype registry

Step 4
Let the client use the registry to access prototype instances

Requirement :
Create Permanent Employee and Contract employee instances based on the input passed and create these objects just by cloning as its creation is costly process.

Detailed Solution for the above requirement

Step 1

First define a prototype interface by declaring a clone method

  1. Public interface Employee{
  2. String name;
  3. String empId;
  4. Float salary;
  5. Employee clone();
  6. }
Public interface Employee{
String name;
String empId;
Float salary;
Employee clone();
}

Step 2

Define multiple concrete prototype classes which implements the “Prototype” interface and define the clone() method as per the need

  1. Public class PermanentEmployee implements Employee{
  2. float bonus;
  3. public Employee clone(){
  4. Employee e = new PermanentEmployee();
  5. e.name="John";
  6. e.empId="p10001";
  7. e.salary=24500.50f;
  8. e.bonus=10250.50f;
  9. return e;
  10. }
  11. @Override
  12.     public String toString() {
  13.         return empId;
  14.     }
  15.  
  16. }
Public class PermanentEmployee implements Employee{
float bonus;
public Employee clone(){
Employee e = new PermanentEmployee();
e.name="John";
e.empId="p10001";
e.salary=24500.50f;
e.bonus=10250.50f;
return e;
}
@Override
    public String toString() {
        return empId;
    }

}

  1. Public class ContractorEmployee implements Employee{
  2. int contractYears;
  3. public Employee clone(){
  4. Employee e = new ContractorEmployee();
  5. e.name="Peter";
  6. e.empId="c10001";
  7. e.salary=18500.50f;
  8. e. contractYears =2;
  9. return e;
  10. }
  11. @Override
  12.     public String toString() {
  13.         return empId;
  14.     }
  15.  
  16. }
Public class ContractorEmployee implements Employee{
int contractYears;
public Employee clone(){
Employee e = new ContractorEmployee();
e.name="Peter";
e.empId="c10001";
e.salary=18500.50f;
e. contractYears =2;
return e;
}
@Override
    public String toString() {
        return empId;
    }

}

Step 3

Add all the prototypes to a prototype registry

  1. Public class EmployeeRegistry{
  2. Private static Map<String,Employee> prototypes = new HashMap<>();
  3. Static{
  4. prototypes.put("pEmp",new PermanentEmployee());
  5. prototypes.put("cEmp",new ContractorEmployee());
  6. }
  7. Public Employee getEmployee(String type){
  8. try{
  9. return prototypes.get(type).clone();
  10.  
  11. }
  12. catch (NullPointerException e) {
  13.             System.out.println("Prototype with name: " + type + ", doesn't exist");
  14.             return null;
  15.         }
  16.  }  //close of method
  17. } //close of class
Public class EmployeeRegistry{
Private static Map<String,Employee> prototypes = new HashMap<>();
Static{
prototypes.put("pEmp",new PermanentEmployee());
prototypes.put("cEmp",new ContractorEmployee());
}
Public Employee getEmployee(String type){
try{
return prototypes.get(type).clone();

}
catch (NullPointerException e) {
            System.out.println("Prototype with name: " + type + ", doesn't exist");
            return null;
        }
 }  //close of method
} //close of class

Step 4

Let the client use the registry to access prototype instances

  1. public class PrototypePatternClient
  2. {
  3.     public static void main(String[] args)
  4.     {
  5.             Employee  pEmp  = EmployeeRegistry.getEmployee("pEmp");
  6.             System.out.println(pEmp);
  7.  
  8.            Employee  cEmp  = EmployeeRegistry.getEmployee("cEmp");
  9.             System.out.println(cEmp);
  10.  
  11. //Modify the cloned object as per need
  12.            Employee  cEmp1  = EmployeeRegistry.getEmployee("cEmp");
  13. cEmp1.contractYears=3;
  14. //Modify any other fields if required for new object
  15.    
  16.     }
  17. }
public class PrototypePatternClient
{
    public static void main(String[] args)
    {
            Employee  pEmp  = EmployeeRegistry.getEmployee("pEmp");
            System.out.println(pEmp);
 
           Employee  cEmp  = EmployeeRegistry.getEmployee("cEmp");
            System.out.println(cEmp);

//Modify the cloned object as per need
           Employee  cEmp1  = EmployeeRegistry.getEmployee("cEmp");
cEmp1.contractYears=3;
//Modify any other fields if required for new object
    
    }
}



When to use this pattern?


When creating an object is a costly and time-consuming operation and, in that case, copying an object would be easier.

New objects required are almost similar to the existing objects.

Note:
We should always have good knowledge about the data of the object that is to be cloned and also make sure that cloned instance allows us to make changes to the data. If not, after cloning we will not be able to make required changes to the cloned object to get the object as per the need.

About the Author

Karibasappa G C (KB)
Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on

Comment (10)

  1. Hello

    I really liked your blog.however in this post i would like to add something ,

    you have mentioned there that

    *How we create object in Java ?

    Yes using constructor , and we should not allow users to access constructor and execute it every time they try to. *

    I believe this statement is completely wrong. constructor is executed that does not mean object is created. object is create only using new operator and constructor is executed to initialize the instance variable.

    Kindly correct it.. 🙂

    thanks again.

    1. Karibasappa G C (KB)
      Karibasappa G C (KB)

      Thanks PushP for bringing this into discussion!!

      Let me try to make you understand the below line
      we should not allow users to access constructor and execute it every time they try to.

      If we are making someone to access constructor I mean execute constructor multiple times it just creates new object according to Java concept.

      How ?
      you know that constructors don’t have names right,so the only we to make the constructor execution is by creating an object using new.
      I agree that constructor execution and object creation are different activities but my point here is when you allow someone to execute the constructor multiple times, it means you are calling constructors multiple times because there is no other way to execute the constructors.
      Note:going through programmatically not through reflection and all.

      your opinion
      constructor is executed that does not mean object is created , object is created only using new operator and constructor is executed to initialize the instance variable

      my understanding on your opinion
      if I go by English i agree with this sentence , but going by Java concept i can not agree with this.
      Because when constructor is executed it means that you have called it using new class_name(), it means one object gets created in Java.
      I am not saying constructor execution and object creation are synonyms but what i am saying is they are mutually dependent.

      So my point here is simple,
      we should not allow users create object multiple times which is same as we should not allow users to execute the constructors multiple times.

      preventing constructor execution is same as not allowing someone to create an object.

      Happy to hear your inputs again and Thank you so much !!

  2. karibasappagc

    Hi Mani,,,

    I have added subscribe option on the right sidebar, you can subscribe there to receive the updates 🙂

    Thank you once again…and welcome for your comments always.

  3. karibasappagc

    Hi Mani, Its really very good notice…

    I forgot to add clone and also i didn’t add one more approach using ENUM.

    But Reflection you are right , i didnt notice this situation. but its good to cover that as well.

    so i will edit this post sometime to include all the above scenarios.

    Thanks a lot for reading , observing the things and suggesting.

    Keep Suggesting the posts during your free time 🙂 Thank you once again…

  4. Manikandan Jayaraman

    Good one, KB 🙂

    I can break your code using reflection though:
    ===
    // Access constructor using reflection
    Class clazz = FinalSingleton.class;
    Constructor cons = clazz.getDeclaredConstructor();
    cons.setAccessible(true);
    FinalSingleton instanceThree = cons.newInstance();
    instanceThree.setX(300);
    System.out.println(“instanceThree.getX() :: “+instanceThree.getX());
    ===

    the above creates a new instance.you can avoid that by changig your constructor
    ===
    private FinalSingleton() {

    //If-block needed to avoid creation of another object using reflection
    /*if (LazyLoadFinalSingleton.SINGLETONINSTANCE != null) {
    throw new IllegalStateException(“Inside FinalSingleton(): instance already created.”);
    }*/

    x = 100;
    System.out.println(“Constructor Called. Instance created.”);
    }
    ===

    Also good to override clone method and throw clone not supported exception. You will never know where the loop hole is. 🙂

Leave a Comment

  • You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code lang=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" extra="">

    • Please answer this simple challenge to post your valuable comment *