Prototype Design Pattern
In this post, We will take a look at prototype design pattern in java with an example.
What is Prototype Pattern?
The prototype Design pattern is a creational pattern that deals with creating objects quickly through cloning. This pattern is helpful when an object would take less time to initialize than through constructors. Also, this pattern makes sure your code doesn’t depend on the classes of the objects.
Implementation with a real-world example
Let’s say you are an author writing a book. The book will take some time to publish because you need to put the effort into writing the content. However, once you have authored the book, now it is easy to make a clone of that said book. We could make a demonstration of the prototype pattern with a Java class.
public class Book {
public static final Logger logger = LoggerFactory.getLogger(Book.class);
private final String title;
private final String isbn;
public Book(String title, String isbn) throws InterruptedException {
this.title = title;
this.isbn = isbn;
logger.info("Waiting 5 seconds simulate Book authoring..!");
Thread.sleep(5000);
}
}
Code language: Java (java)
Here we deliberately added a 5 seconds delay in the constructor. So the object should take at least 5 seconds if we use the new
keyword. If we go on and create objects of this class, then our application will perform poorly.
This is where the prototype design pattern shines.
Clonable product class
So instead of using the constructor method to create new objects, We could clone the existing object with less time. The cloning process simply copies the data over to the new object. So there is no time wasted.
public class Book implements Cloneable {
public static final Logger logger = LoggerFactory.getLogger(Book.class);
private final String title;
private final String isbn;
public Book(String title, String isbn) throws InterruptedException {
this.title = title;
this.isbn = isbn;
logger.info("Waiting 5 seconds simulate Book authoring..!");
Thread.sleep(5000);
}
public Book clone() throws CloneNotSupportedException {
return (Book)super.clone();
}
@Override
public String toString() {
return "Book{" +
"title='" + title + '\'' +
", isbn='" + isbn + '\'' +
", hashcode='" + hashCode() + '\'' +
'}';
}
}
Code language: Java (java)
Prototype pattern in Action
In the above class, we introduced the clone()
method. This method is a java built-in method that copies the content of any object and replicates it to another. Let’s see how this approach performs.
public static void main(String[] args) throws CloneNotSupportedException, InterruptedException {
logger.info("Creating first book manually using constructor....!");
Book book = new Book("HHH", "YYYY");
logger.info("Original : {}",book);
logger.info("Now cloning the book...!");
Book clone = book.clone();
logger.info("Cloned : {}",clone);
logger.info("Cloned book has less creation time...!");
}
Code language: PHP (php)
The above snippet creates a book and then tries to clone it. As you see in the below output, the original tool 5 seconds to spawn. But the cloned object is created immediately. This tells us that the prototype design pattern helped solve the performance problem with our java class.
Also if you pay attention to the object details, the hash code for both objects would be different. This behaviour tells us that both book and clone variables reference entirely different objects.
When to use prototype pattern?
This pattern is appropriate when creating clones are faster than creating objects using the new
keyword. Clones can be helpful in the place of transactions. For example, We could easily clone the current representation, perform operations on it, and if all succeed, we can simply replace the original.
Prototype pattern can be mixed with Factory pattern and Builder Pattern as you would constantly be creating the same object again and again. In some cases, these three patterns even complement each other.
Disadvantages
Some of these disadvantages are not directly from the pattern itself but from how we implement them. For example, Object.clone()
clones everything including private fields. This may be a bad thing for information security.
Summary
To sum it up, We learned about prototype design pattern and how to implement them in java with an example. Like always, you can find all source-code in our design-patterns GitHub repo.