Prototype Design Pattern: Whenever in JAVA we are making a clone of a Java Object means we are using Prototype Design Pattern.
Any Java object can be cloned only if it implements java.lang.Cloneable interface wihc is just a marker interface means you are allowing JVM to make the clone of this object and the class should override the clone method of Object class, this method of Object class is protected so you will have to make it public by overriding it.
Shallow and Deep Cloning: If the Object1 is having any reference to Object2 and you are making clone of Object1 only then in this case the new clone of Object1 will have the reference to same Object2 which is shallow cloning. If new clone of Object1 is also refering the clone of Object2 menas it is a Deep cloning. So in deep cloning no object should point out to original object reference.
Uses: It is used mainly in the situation when object creation is costly or time time consuming like creating an object using constrctor taks a lot of time. If you are planning to make a pool reusable objects then make only one object and then make copies of this new object by cloning and put them in pool.
Example: Below example shows the difference between creating an object by calling constructor and clone. We can see that clong is taking very less time in comparision to creating a new object by calling constructor.
package org.paandav.prototype;
public class Prototype implements Cloneable {
public Prototype() {
for (int i = 0; i < 10000000; i++) {
// pass some time.
}
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package org.paandav.prototype;
public class PrototypeTest {
public static void main(String[] args) throws Exception {
long start = System.nanoTime();
Prototype pt = new Prototype();
long stop = System.nanoTime();
System.out.println("Time taken to create a new object="
+ (stop - start));
start = System.nanoTime();
Prototype ptClone = (Prototype) pt.clone();
stop = System.nanoTime();
System.out.println("Time taken to create clone object="
+ (stop - start));
}
}
Shallow and Deep Cloning example:
package org.paandav.prototype;
public class Prototype2 {
}
package org.paandav.prototype;
public class Prototype2 implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package org.paandav.prototype;
public class Prototype implements Cloneable {
Prototype2 pt2 = null;
public Prototype() {
pt2 = new Prototype2();
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Both above classes shows an example of Shallow Cloning because when you will make a clone of Prototype object it will refer to same Prototype2 object.
To do the Deep cloning use the below Prototype classes
package org.paandav.prototype;
public class Prototype2 implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package org.paandav.prototype;
public class Prototype implements Cloneable {
Prototype2 pt2 = null;
public Prototype() {
pt2 = new Prototype2();
}
public void setPt2(Prototype2 pt2) {
this.pt2 = pt2;
}
public Prototype2 getPt2() {
return pt2;
}
@Override
public Object clone() throws CloneNotSupportedException {
Prototype pt = (Prototype) super.clone();
pt.setPt2((Prototype2) pt.getPt2().clone());
return pt;
}
}
Thanks for your post. I’ve been thinking about writing a very comparable post over the last couple of weeks, I’ll probably keep it short and sweet and link to this instead if that’s cool. Thanks.
ReplyDeleteDesign Prototype