A prototype is a template of any object before the actual object is constructed. In Java, it also has the same meaning. The prototype design pattern is used in scenarios where an application needs to create a number of instances of a class that have almost the same state or differ very little.
The prototype pattern is a creational design pattern in software development. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects.
In the prototype design pattern, an instance of the actual object (i.e., prototype) is created in the beginning, and thereafter, whenever a new instance is required, this prototype is cloned to have another instance. The main advantage of this pattern is that it has a minimal instance creation process, which is much more costly than the cloning process.
Please ensure that you want to deep clone or shallow clone your prototype because both will have different behavior on runtime. If deep copy is needed, you can use a good technique given here using in memory serialization.
1. Design Participants
- Prototype: This is the prototype of the actual object, as discussed above.
- Prototype registry: This is used as a registry service to have all prototypes accessible using simple string parameters.
- Client: The client will be responsible for using the registry service to access prototype instances.
2. Problem Statement
Let’s understand the prototype pattern using an example. We are creating an entertainment application that will frequently require instances of the Movie, Album, and Show classes.
We do not want to create and initialize these instances every time, as it is costly. So, I will create their prototype instances, and every time I need a new instance, I will just clone the prototype.
3. Prototype Design
Let’s start by creating a class diagram.

The above class diagram explains the necessary classes and their relationship.
Only one interface, “PrototypeCapable” is new addition in solution. The reason to use this interface is broken behavior of Cloneable interface. This interface helps in achieving the following goals:
- Ability to clone prototypes without knowing their actual types
- Provides a type reference to be used in the registry
Their workflow will look like this:

4. Prototype Pettern Implementation
Lets hit the keyboard and compose these classes.
PrototypeCapable.java
public interface PrototypeCapable extends Cloneable {
public PrototypeCapable clone() throws CloneNotSupportedException;
}
Movie.java, Album.java and Show.java
// Movie.java
public class Movie implements PrototypeCapable {
private String name = null;
// Getter and Setter
@Override
public Movie clone() throws CloneNotSupportedException {
System.out.println("Cloning Movie object..");
return (Movie) super.clone();
}
@Override
public String toString() {
return "Movie";
}
}
// Album.java
public class Album implements PrototypeCapable {
private String name = null;
// Getter and Setter
@Override
public Album clone() throws CloneNotSupportedException {
System.out.println("Cloning Album object..");
return (Album) super.clone();
}
@Override
public String toString() {
return "Album";
}
}
// Show.java
public class Show implements PrototypeCapable {
private String name = null;
// Getter and Setter
@Override
public Show clone() throws CloneNotSupportedException {
System.out.println("Cloning Show object..");
return (Show) super.clone();
}
@Override
public String toString() {
return "Show";
}
}
PrototypeFactory.java
public class PrototypeFactory {
public static class ModelType {
public static final String MOVIE = "movie";
public static final String ALBUM = "album";
public static final String SHOW = "show";
}
private static java.util.Map<String , PrototypeCapable> prototypes
= new java.util.HashMap<String , PrototypeCapable>();
static {
prototypes.put(ModelType.MOVIE, new Movie());
prototypes.put(ModelType.ALBUM, new Album());
prototypes.put(ModelType.SHOW, new Show());
}
public static PrototypeCapable getInstance(final String s) throws CloneNotSupportedException {
return ((PrototypeCapable) prototypes.get(s)).clone();
}
}
5. Demo
Lets test the implementation by creating new objects using the prototypes.
public class TestPrototypePattern {
public static void main(String[] args) {
try {
String moviePrototype = PrototypeFactory.getInstance(ModelType.MOVIE).toString();
System.out.println(moviePrototype);
String albumPrototype = PrototypeFactory.getInstance(ModelType.ALBUM).toString();
System.out.println(albumPrototype);
String showPrototype = PrototypeFactory.getInstance(ModelType.SHOW).toString();
System.out.println(showPrototype);
} catch (CloneNotSupportedException e){
e.printStackTrace();
}
}
}
When you run the client code, the following is the output.
Cloning Movie object..
Movie
Cloning Album object..
Album
Cloning Show object..
Show
6. When to use?
When an object is required that is similar to an existing object or when the creation would be expensive compared to cloning.
I hope you liked this post on a Java prototype pattern example. If you have any questions, drop a comment.
Happy Learning !!
Comments