Core Java

Java Prototype Design Pattern Example

1. Introduction to Java Prototype Design Pattern

In this article, we would be discussing in depth the Java Prototype Design pattern. Java Prototype Design pattern is a creational design pattern that provides a way of prototyping objects of similar nature. In Java, the creation of objects is an expensive job in terms of the processing power being consumed. In case of web applications, a badly designed application normally creates a new object of every involved class for every new request coming in. This adds to the latency factor of the request-response cycle. This can be resolved by following a specific design pattern that cuts this overhead and provides the already available object instances. The prototype design pattern, as the name suggests, helps in eliminating this overhead of creating the object repeatedly. In this article, we will try to understand where exactly does the prototype design pattern fit in and how can we create classes in a prototype design pattern.

 

The article would begin with the explanation of various available design patterns following which we understand the prototype design pattern with a real-life example. This would help in understanding when precisely should you use the Java Prototype design pattern. Once this has been understood, we would proceed towards understanding how exactly should you code the classes in order to implement a prototype design pattern.

2. Types of Java Design Patterns

There are various design patterns characterized in Java to fill the need of a sorted out advancement. The following are a group of real pattern clarified for your comprehension. As we continue in the article, we will comprehend the Java Abstract Factory design in detail with precedent.

2.1 Creational Pattern

In article creation, creational design patterns happens. They render the creation procedure substantially more effective and inventive. Inventive patterns specifically can convey a wide scope of decisions concerning which objects are created, how every one of these articles are delivered and how they are initialised. This pattern can once in a while be marked into either class and even article creation patterns. Despite the fact that class-creation patterns viably use legacy in the establishment procedure, where object-creation patterns adequately utilize high – level assignment to complete all the activity legitimately. The creational design patterns are additionally part into six distinctive design pattern types

The creational design patterns play extremely important role in web applications and memory intensive applications. The creational patterns form the core of popular frameworks like Spring Framework and Hibernate ORM framework. These frameworks focus on the provisioning of object to the classes as needed. They help in managing the objects, caching of data and also garbage collection. This processes are possible in a perfect manner only when the design patterns are strictly followed.

2.2 Structural Pattern

Structural pattern design portrays seven unique kinds of design patterns. Structural design patterns are design patterns which advance design by recognizing a snappy and simple method for passing on connections between the items. Such design patterns concentrate intensely upon how classes and items could be connected to shape bigger systems. The structural design patterns attempt to improve or advance the structure by understanding the distinction between the structural components. They help in structuring the object creation or the creational pattern classes in a way that their dependencies are managed well.

2.3 Behavioral Pattern

These design patterns really identify with the class-to-protest correspondence. Social design patterns are a few patterns which influence correspondence between items generally explicitly. This pattern describes eleven distinctive pattern classifications for association among items. These design patterns are being utilized to manage object calculations, connections and obligations. They guide the communication mechanisms between different objects.

In this article, we discuss one of the creational pattern that guides in the creation of classes that reduce the overall object provisioning time. This is made possible by eliminating the process of data fetching & initialization for every new object. It also helps in creating copies of objects faster than the conventional way of doing it.

3. Prototype Design Pattern – Real life example

In this section, we will take you through a real life analogy of the prototype design pattern. This example will explain how exactly does prototype design pattern help in reducing the time taken for the creation of objects. We would be taking the example of the creation of new mobile phones models to understand how it is similar to prototype design pattern.

Below image shows the simple process of how the mobile phones companies create variants of their mobile phones. The brands presented in the image are just for depiction purpose and holds no direct relation.

Java Prototype Design Pattern - Prototype Design Pattern Real World example
Prototype Design Pattern Real World example

As shown in the above image, consider the process of how the first mobile phone model of a specific design and shape is made. It goes through the process of designing, prototyping, development of relevant system software and various testing cycles. These processes finally output the first variant of any specific device model. In the above image, consider the first variant to be created as part of the development of a complete range of variants. Now, when the company plans to release more variants which are similar with slight upgrades or changes, the company has the benefit of re-using a lot of items like the motherboard, the processor configurations, screen or keypads, camera sensors and many such other components. This reduces the time taken in the testing cycles. Thus, the overall turnaround time for the new phone variants is lesser than the time taken by the first phone.

In this manner, prototype design pattern utilises processing memory and time to create the first object. It fetches all the required data and stores in the memory. The next time when an object is required, the prototype class clones the object and allows to customise the required parameters later. The overhead of fetching the data or processing the inputs is eliminated. A prototype pattern is normally used when the objects are initialised at the beginning of an application and used repeatedly thereafter. An excellent use of this pattern could be in the execution of machine learning models where for certain data set objects only the value of one or two variables change. In a processing power hungry application like the Machine learning model evaluation, prototype design pattern certainly comes in handy.

Another similar scenario where prototype design pattern actually comes in handy is Web applications. In Java web applications, the developers utilise Hibernate ORM framework or JPA annotations to enable prototyping of database objects. These objects are cached on startup of the web application and hence eliminates the time taken in fetching the data each time from the database. Such prototype objects are normally used for passing repeated data like the list of countries, states, cities, salutations, qualifications and others.

4. Implementing Prototype Design Pattern

Let us now get going towards implementing the prototype design pattern manually. We will take a scenario of fetching a user list in a simple application. In such a scenario, the normal process of object creation is that the data will be created or fetched from the database each time the new object is created.

However, with the Prototype design pattern, we would understand how the overhead of fetching or creating the data is eliminated. Create the Java classes as shown below.

UserService.java

package com.classes;

public class User {
	String name;
	String email;
	
	public User(String name,String email) {
		this.name= name;
		this.email = email;
	}
	
	public String toString() {
		return "Name of user:"+this.name+"\nEmail of User:"+this.email;
	}
}

User.java

package com.service;

import java.util.ArrayList;

import com.classes.User;

public class UserService {
	ArrayList users;
	
	public UserService() {
		users = new ArrayList();
		users.add(new User("Albert","albert@gmail.com"));
		users.add(new User("Bob","bob@gmail.com"));
		users.add(new User("Gary","gary@gmail.com"));
		users.add(new User("Geno","geno@gmail.com"));
	}
	public ArrayList getUsers(){
		return users;
	}
}

The above two classes present the base object class User that helps in creating the list of users. The second class created above is a service that would in a real world application help in fetching a list of users existing in the database. Currently it just mocks the service call and loads the data into list by creating it.

Now, we will proceed towards creation of actual prototyping class. This class will implement the Java Clonable interface. This is an interface that enforces the class to override the method clone(). This method is used to allow cloning of objects without going for fetching the data again. Cloning will provide a clone of existing object in a new object instance. This means that all the data in both the object will be same but they will refer to a different location. Let us now create the class and understand the same further.

UserDetails.java

package com.classes;

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

import com.service.UserService;

public class UserDetails implements Cloneable{
	private ArrayList userList;
	
	public UserDetails() {
		this.userList=new ArrayList<>();
	}
	
	public UserDetails(ArrayList users) {
		this.userList = users;
	}
	
	public void getUsers() {
		UserService s = new UserService();
		this.userList = s.getUsers();
	}
	
	public ArrayList getUsersList(){
		return userList;
	}
	@Override
	public Object clone() throws CloneNotSupportedException{
			List temp = new ArrayList();
			for(User s : this.getUsersList()){
				temp.add(s);
			}
			return new UserDetails((ArrayList) temp);
	}
}

As it can be seen, the class provides a function clone(). This function will be further used to obtain cloned objects. This function uses the existing list of users and creates a new list out of it. It does not go for a service call as it can be noted. This ensures that the application does not hit the database repeatedly and all the objects have the required data with just one hit.This saves the overhead of database calls and results in extremely good performance thereafter.
Let us now create an implementation class with the main function.

ImplementorClass.java

package com.javacodegeeks;

import java.util.List;

import com.classes.User;
import com.classes.UserDetails;

public class ImplementorClass {
	public static void main(String[] args) {
		UserDetails users = new UserDetails();
		users.getUsers();

		// Use the clone method to get the Employee object
		UserDetails usersNew;
		try {
			usersNew = (UserDetails) users.clone();
			UserDetails usersNew1 = (UserDetails) users.clone();
			List list = usersNew.getUsersList();
			list.add(new User("Tim", "tim@gmail.com"));
			List list1 = usersNew1.getUsersList();
			list1.remove(new User("steve", "steve@gmail.com"));

			System.out.println("users List: " + users.getUsersList());
			System.out.println("usersNew List: " + list);
			System.out.println("usersNew1 List: " + list1);
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

The above function creates a user object and loads the data into it. Once this data is loaded, the function clones the object into two more objects. Further, the additional data is added into each of them. Now, on running the program, we get the below output.

users List: [Name of user:Albert
Email of User:albert@gmail.com, Name of user:Bob
Email of User:bob@gmail.com, Name of user:Gary
Email of User:gary@gmail.com, Name of user:Geno
Email of User:geno@gmail.com]
usersNew List: [Name of user:Albert
Email of User:albert@gmail.com, Name of user:Bob
Email of User:bob@gmail.com, Name of user:Gary
Email of User:gary@gmail.com, Name of user:Geno
Email of User:geno@gmail.com, Name of user:Tim
Email of User:tim@gmail.com]
usersNew1 List: [Name of user:Albert
Email of User:albert@gmail.com, Name of user:Bob
Email of User:bob@gmail.com, Name of user:Gary
Email of User:gary@gmail.com, Name of user:Geno
Email of User:geno@gmail.com]

As it can be seen, the object clones contain the data separately. Each cloned object instance has the data from the actual object along with the new data that is being added to it. In this manner, the object prototypes can be created without calling the service again.

5. Benefits of prototype Design Pattern

The prototype design pattern has been developed and is being used by a number of popular frameworks in Java. In fact, one of the bean scopes in the Spring framework is the prototype scope. This scope signifies the creation of a new object each time it is required. This pattern has a lot of benefits. A few of them are listed below:

  • Provides a lower latency in creation of objects
  • Provides easier way of cloning objects
  • Reduces the load on the database for fetching the data
  • Improves overall application performance
  • Reduces the effort of cloning an object for the application developer
  • Make the cloning code independent of the implementing classes
  • Allows you to easily modify the existing class and its prototyping function which would not have been the case if cloning takes place elsewhere

6. Conclusion

The prototype design pattern is widely used and preferred in frameworks like Spring, Hibernate and Struts. It is of great use when an application demands repeated creation of similar objects. In the prototype design pattern, every class that requires prototyping, implements the Clonable interface and overrides the relevant function.

7. Download the Project

You can download the project files for the above example from the link below

Download
You can download the full source code of this example here: PrototypeDesignPattern.zip

Abhishek Kothari

Abhishek is a Web Developer with diverse skills across multiple Web development technologies. During his professional career, he has worked on numerous enterprise level applications and understood the technological architecture and complexities involved in making an exceptional project. His passion to share knowledge among the community through various mediums has led him towards being a Professional Online Trainer, Youtuber as well as Technical Content Writer.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button