When creating an object is time consuming and a costly affair and you already have a most similar object instance in hand, then you go for prototype pattern. Instead of going through a time consuming process to create a complex object, just copy the existing similar object and modify it according to your needs.
Its a simple and straight forward design pattern. Nothing much hidden beneath it. If you don’t have much experience with enterprise grade huge application, you may not have experience in creating a complex / time consuming instance. All you might have done is use the new operator or inject and instantiate.
If you are a beginner you might be wondering, why all the fuss about prototye design pattern and do we really need this design pattern? Just ignore, all the big guys requires it. For you, just understand the pattern and sleep over it. You may require it one day in future.
Prototype pattern may look similar to builder design pattern. There is a huge difference to it. If you remember, “the same construction process can create different representations” is the key in builder pattern. But not in the case of prototype pattern.
So, how to implement the prototype design pattern? You just have to copy the existing instance in hand. When you say copy in java, immediately cloning comes into picture. Thats why when you read about prototype pattern, all the literature invariably refers java cloning.
Simple way is, clone the existing instance in hand and then make the required update to the cloned instance so that you will get the object you need. Other way is, tweak the cloning method itself to suit your new object creation need. Therefore whenever you clone that object you will directly get the new object of desire without modifying the created object explicitly.
The prototype design pattern mandates that the instance which you are going to copy should provide the copying feature. It should not be done by an external utility or provider.
But the above, other way comes with a caution. If somebody who is not aware of your tweaking the clone business logic uses it, he will be in issue. Since what he has in hand is not the exact clone. You can go for a custom method which calls the clone internally and then modifies it according to the need. Which will be a better approach.
Always remember while using clone to copy, whether you need a shallow copy or deep copy. Decide based on your business needs. If you need a deep copy, you can use serialization as a hack to get the deep copy done. Using clone to copy is entirey a design decision while implementing the prototype design pattern. Clone is not a mandatory choice for prototype pattern.
In prototype pattern, you should always make sure that you are well knowledgeable about the data of the object that is to be cloned. Also make sure that instance allows you to make changes to the data. If not, after cloning you will not be able to make required changes to get the new required object.
Following sample java source code demonstrates the prototype pattern. I have a basic bike in hand with four gears. When I want to make a different object, an advance bike with six gears I copy the existing instance. Then make necessary modifications to the copied instance. Thus the prototype pattern is implemented. Example source code is just to demonstrate the design pattern, please don’t read too much out of it. I wanted to make things as simple as possible.
package com.javapapers.sample.designpattern.prototype; class Bike implements Cloneable { private int gears; private String bikeType; private String model; public Bike() { bikeType = "Standard"; model = "Leopard"; gears = 4; } public Bike clone() { return new Bike(); } public void makeAdvanced() { bikeType = "Advanced"; model = "Jaguar"; gears = 6; } public String getModel(){ return model; } } public class Workshop { public Bike makeJaguar(Bike basicBike) { basicBike.makeAdvanced(); return basicBike; } public static void main(String args[]){ Bike bike = new Bike(); Bike basicBike = bike.clone(); Workshop workShop = new Workshop(); Bike advancedBike = workShop.makeJaguar(basicBike); System.out.println("Prototype Design Pattern: "+advancedBike.getModel()); } }
Comments are closed for "Prototype Design Pattern".
Nice post
[code]
public Bike clone() {
return new Bike();
}
[/code]
Using new operator for cloning is wrong pattern to use. Even though for the sake of current need it works fine, we should never use new operator in clone method instead you should use super.clone() and typecast it to Bike.
– Pa1
I was thinking the same, where’s the advantage of cloning over new since you use new in the clone() method? :)
This example is actually wrong. If you use “NEW” operator you just simply create new Object of the same type and of course you can change its characteristics without problems :).
I agree, super.clone() is the correct way to create cloned object..now new***
“class Bike implements Cloneable”
Where is definition of “Cloneable” in this example?
can u pls explain more design patterns.
Xellent….. :)Help me preparing lab viva…
Thanks, it was good article. :)
Replace:
public Bike clone() {
return new Bike();
}
WITH:
public Bike clone() {
//return new Bike();
Bike byk=null;
try{
byk=(Bike)super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(e.getMessage());
}
return byk;
}
It’s very useful , kindly explain more patterns.
Thank you!!! Good article.
super.clone calls the objects class clone method then we ouself doncasting it to the Bike type i think its best way to use protype design pattern.
Good blog
It is indeed a good blog
I like your explanation,Thanks for your effort.
Where is this used ? any example scenarios or incase used in java api?
Thanks!
yes you have to use shallow copy or deep copy for cloning
Hey Joe, I guess all the above discussion over using new operator to clone is because people not understanding that you tried using deep cloning. If I understand correctly when you did
public Bike clone() {
/* This is deep clone of Bike Object*/
return new Bike();
}
but if you call super.clone then only shallow cloning takes place.
Its purely a design choice..I doubt anything wrong here
Amit
I didn’t get this idea..So if you don’t have much time to create new object then how you will manage time by writing workshop class? and also you are just changing the value of the properties and not the actual object? Also you have a authority to modify already written class(for making object). Because in some big org you cant not just modify code of your super classes of framework.?
thank u !!
i learned alot from this
good work
MakeAdvanced() method should be some other class Let’s sat BikeLatest which inherits the Bike class
What is the use of creating Workshop class? Also, no need to create 2 objects to get advanced bike. Just:
Bike advBike = bike.clone();
advBike.makeAdvanced();
would suffice?
can u give sample code in java for maze game….
can you help me undestand the meaning of what is going on that code each line of it .
i have a presentation next week help me undestand each line of that code i know its all about cloning.fully details will be apreciated
thanks, your article is good, but for modern jvm clone is costlier than new operator i think
Thanks! This article is really good.
Sorry, but this is not an example of the Prototype Pattern. There is no difference in memory or time consumption between this cloning implementation and just using the ‘new’ operator to create the advanced bike.
@Amit: creating a new object in the clone method is NOT an example of deep copy. A clone method that performed memberwise cloning would be a deep copy.
The point of Prototype Pattern is that the creation of the object is expensive. If the creation involved reading from disk, network communication, or a database read then you want to avoid repeating those steps. Using the new operator in the clone method does not help avoid this.
Somebody please explain what needs to be modified in the source code to fit this example to prototype Design Pattern . At least
Joe please explain. All people comments are making me to get Confusion only . Thanks in advance.
This example is wrong. In prototype pattern we should not use the “new” keyword. We need to clone the object (Deep copy or shallow based on situation), that’s the purpose of prototype pattern.
Note: Remember to use this pattern when the cost of creating a new object is large an expensive
Hi Amit, it is not a copy first of all. It is just a new instance if you use NEW in clone method. Deep copy should copy all the properties of the current instance which is getting cloned.
Elavarasan
Everybody complaining about the use of the new keyword in clone method, didn’t you read . . .
“Example source code is just to demonstrate the design pattern, please don’t read too much out of it. I wanted to make things as simple as possible.”
Anotherwards, he spent countless hours putting this website together to share his knowledge with the development community – A simple Thank You would have sufficed.
Shame on you all.
This is wrong…you should use as following:
@Override
public Object clone() throws CloneNotSupportedException {
return (Bike) super.clone();
}
please put class diagram……
very nice. i am not a s/w developer, still i could understand this article
It comes from JDK: java.lang.Cloneable
I regularly follow your articles and they are very clear and insightful. Regarding this article why dont you please comment “new” vs .clone() and suppress this controversy? why did you use “new” as it is a new instance and not a copy at all
example not usefull at all
thank you very much !
that a good work
This is the right and working code
class Bike implements Cloneable {
private int gears;
private String bikeType;
private String model;
public Bike() {
System.out.println(“intilize”);
bikeType = “Standard”;
model = “Leopard”;
gears = 4;
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public void makeAdvanced() {
bikeType = “Advanced”;
model = “Jaguar”;
gears = 6;
}
public String getModel(){
return model;
}
/**
* @return the gears
*/
public int getGears() {
return gears;
}
/**
* @param gears the gears to set
*/
public void setGears(int gears) {
this.gears = gears;
}
}
public class Workshop_prot {
public Bike makeJaguar(Bike basicBike) {
basicBike.makeAdvanced();
return basicBike;
}
public static void main(String args[]) throws CloneNotSupportedException{
Bike bike = new Bike();
Bike basicBike = (Bike) bike.clone();
Workshop_prot workShop = new Workshop_prot();
Bike advancedBike = workShop.makeJaguar(basicBike);
System.out.println(“Prototype Design Pattern: “+advancedBike.getModel()+”gears: “+advancedBike.getGears());
}
}
First of all, a BIG thank you Joe for taking the effort to write this blog which provides simple explanations for java related queries. It is really useful.
I can see many comments saying this example is wrong, incorrect etc. I would ask all of them to read the article once again. There are two types of cloning – shallow copy(which has its own disadvantages) and deep copy. In this article Joe used deep copy. Of course deep copy needs to instantiate the object and set all its property manually. But Joe wanted to keep the code simple which is why he wrote
“Example source code is just to demonstrate the design pattern, please don’t read too much out of it. I wanted to make things as simple as possible.”
If you wanted know the difference between deep copy and shallow copy , its advantages and disadvantages he has already posted the link for the same in the article. For those who didn’t care to read’em here it is – https://javapapers.com/core-java/java-clone-shallow-copy-and-deep-copy/
Oh my God, someone does really understands it. Thanks a lot Sharath. You have exactly nailed it.
I give more preference to simplicity. Please do not read too much out of the examples.
package com.designpattern.creational.prototype;
public class PrototypeDesignPattern {
public Bike makeJaguar(Bike basicBike) {
basicBike.makeAdvanced();
return basicBike;
}
public static void main (String args[]) throws CloneNotSupportedException{
Bike bike = new Bike();
Bike basicBike = bike.clone();
PrototypeDesignPattern workShop = new PrototypeDesignPattern();
Bike advancedBike = workShop.makeJaguar(basicBike);
System.out.println(“Prototype Design Pattern: “+advancedBike.getModel());
}
}
class Bike implements Cloneable {
private int gears;
private String bikeType;
private String model;
public Bike() {
bikeType = “Standard”;
model = “Leopard”;
gears = 4;
}
public Bike clone() throws CloneNotSupportedException{
return (Bike) super.clone();
}
public void makeAdvanced() {
bikeType = “Advanced”;
model = “Jaguar”;
gears = 6;
}
public String getModel(){
return model;
}
}
Correct source code above as given