The above image showcases a skeleton, all of us humans have a basic skeleton and then we differentiate ourselves from different muscle structure, skin tones and so on. Just like that Prototype design pattern will also have a sample object in which multiple different copies will be created.
This is the part 3 of the design patterns article that I have been writing, the links for the previous ones is posted at the end of the article. Check the first link if you are new to Design patterns before reading this article. Now that introductions are over lets talk about Prototype Design Pattern.
What is Prototype Design Patten?
Prototype Design Pattern comes under the creational design pattern. Just like the previous two design patterns we will not be using the new keyword to explicitly create an object. But this is also where prototype design pattern differentiates itself from the singleton and the factory design pattern. In Prototype Design pattern instead of calling the constructor to create instances we will be cloning a premade instance and then change the necessary information for use. In order to do that we will be having a registry class which will create and hold one single instance of the classes that we are going to use.
In order to clone the objects we will be implementing the Cloneable interface and also overriding the clone() method in the parent class. (If you are using only a single class then it can be implemented there.). With this clone() method we will copying from a single instance to create new instances. These new instances will share the same attributes as the original.There are two types of copying that we can use ;
- Shallow Copy
- Deep Copy
I will be showing the implementation of Prototype Design Pattern with shallow copy for the below scenario.
For the implementation we will be implementing a system which sells properties. For that we will be having an abstract class called Property. Look at the below code.
As you can see from above the class has two instance variables which are price and owner. This class does not have custom constructor so the values will be set with the setters. This class has also implemented the Cloneable interface so the clone() method has been overridden. Next with this class I have created two sub classes that extends from the Property class as seen below.
The above classes are the subclasses and these subclasses have a unique property for both of them which is
noOfRoooms for House class and
area for Property class. Just like with the parent class there are no custom constructor for these classes as well. We will be setting the values with setters. They also have a print method as well which will print the details about the sub classes.
We have the sub classes, so the next step is to create the Register class. The following is the implementation for the Register class.
As you can see, the registry class will have a constructor and in this constructor we will be calling the initialize method. (You can directly put the initialization method inside the constructor itself as well). The initialize will be the place where an instance of the sub classes are created, in other words the skeleton object in which every instance will be based off of. And I am using an HashMap to hold the objects that are initialized.
Note: Instead of HashMaps you guys can use the collection class you want like an ArrayList as well, HashMap is good as we can easily identify and get the desired object by parsing the identifier which is the PropertyType enum that I have created.
The next important point to note here is the getProperty() method which will be returning a Property type object. Inside the method the clone method is used and the cloned object will be returned.
Note: As the parent class Property implemented the Cloneable interface the subclasses are also able to use the clone method.
Now that we have all the things that we need the last part is to implement the main method.
The above is my main method, some might think that changing the value in object will also affect the other object but for this scenario it does not occur. As seen from the below output.
The reason for this is that, primitive variables will have a new copy. But you might be thinking String is a reference type, how did it not change even after changing it. The reason is String us immutable so when the string value is changed a new memory area is created for it and the k2 object will be pointing to that.
The above implementation is suitable only for String and primitive types inside an object but if there is another object type used in the subclasses then we can’t do shallow copying and must do deep copying.
Now that we know how to create a prototype pattern there are some important points to take note of when using this pattern.
- This pattern should be used when a large number of objects need to be created, for example an Item list in a shopping application.
- Prototype design pattern skips the creation of new object so it will cut down the time by a good margin as passing in a lot of parameters will increase the running time of applications.
- This design pattern is not used as much as singleton and factory pattern but if your design seems suitable then you should consider using this pattern.
Part 1 Design Pattern : Click Here
Part 2 Design Pattern : Click Here
Click Here to see the above codes in my Github.
This video by Krishantha Dinesh was a huge help to create this article