Learn the Prototype Design Pattern
This is the 6th post in a series on design patterns.
The prototype is a creational design pattern that lets you copy existing objects without making your code dependent on their classes.
Let’s say you want to create an exact copy of an object. How would you go about doing that? You would create a new object of the same class. You must then copy the values of all the fields of the original object to the new one. However, not all objects can be copied that way because some fields of the object may be private and not accessible from outside the object.
There’s one more problem with the direct approach. To duplicate an object, you must know its class, so your code becomes dependent on it. Also, sometimes you only know the interface an object follows, but not its concrete class.
Prototype Design Pattern
In the prototype pattern, cloning is delegated to the actual objects being cloned. This pattern defines a common interface for all objects that support cloning. Using this interface, you can copy an object without coupling your code to the class of the object. Usually, such an interface contains just one clone method. In this method, an object of the current class is created and the old object’s field values are transferred to the new object. A prototype is an object that supports cloning.
UML Class Diagram
Not familiar with UML Class Diagram? I have written a detailed post on the UML Class diagram.
Implementation steps
- Declare the clone method in the prototype interface.
- A prototype class must define an alternative constructor that accepts an object of that class as an argument. All fields defined in the class must be copied into the newly created instance from the passed object.
- In most cases, cloning requires only one line: running the prototypical constructor with a new operator. Every class must explicitly override the cloning method and use its own class name together with the new operator. If not, the cloning method will create an object of the parent class.
Source Code Implementation
The Shape class implements the Cloneable interface to indicate to the Object.clone() method that it is permitted to make field-for-field copies of instances of that class. The CloneNotSupportedException is thrown when Object’s clone method is called on an instance that does not implement the Cloneable interface.
As a convention, classes implementing this interface should override Object.clone (which is protected) with a public method.
The Rectangle class is a subclass of Shape. It overrides the clone method.
PrototypeClient can create a copy of any object that follows the Prototype interface.
//Output
Rectangle [length=10, breadth=20, color=BLUE, hashcode=622488023]
Rectangle [length=10, breadth=20, color=BLUE, hashcode=1933863327]
When To Apply Prototype Design Pattern
- When your code shouldn’t be dependent on the concrete classes of objects that you’re copying, use the prototype pattern.
- When creating an instance of a class that is either expensive or complicated, use the Prototype pattern.
Pros of Prototype Design Pattern
- Objects can be cloned without being coupled to their concrete classes.
- Complex objects can be created more easily.