Definition
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.
As Cloning is a shallow copy of the original object. If the cloned object is changed, the original object will be changed accordingly, so while implementing clone method you need to make sure to use deep copy.
Where to use & benefits:
- avoid subclasses of an object creator in the client application, like the abstract factory pattern does.
- avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it is prohibitively expensive for a given application.
- A system needs independent of how its objects are created, composed, and represented.
- Add and remove objects at runtime.
- The new operator considered harmful
- Related patterns include:
As stated earlier when an object is complicated or time consuming to be created , you may use prototype pattern to make such object cloneable.
Assume the 'Complex' class is a complicated, you need to implement Cloneable interface and override the clone method(protected Object clone()).
package com.meritmix.blog.designpatterns.prototype;
/**
* @author Ravi Yadav
* content for MeritMix.com
* blog address: www.meritmix.com
*/
class Complex implements Cloneable {
int[] nums = {1,2,3,4,5};
public Object clone() {
try {
return super.clone();
}catch(CloneNotSupportedException cnse) {
System.out.println(cnse.getMessage());
return null;
}
}
int[] getNums() {
return nums;
}
}
class Test {
static Complex c1 = new Complex();
static Complex makeCopy() {
return (Complex)c1.clone();
}
public static void main(String[] args) {
Complex c1 = makeCopy();
int[] mycopy = c1.getNums();
for(int i = 0; i < mycopy.length; i++)
System.out.print(mycopy[i]);
}
}
Output:
12345
In the above code, Cloning is actually creating a shallow copy of the original object. If the cloned object is changed, the original object will be changed accordingly. See below changed code to see this behavior.
package com.meritmix.blog.designpatterns.prototype;
/**
* @author Ravi Yadav
* content for MeritMix.com
* blog address: www.meritmix.com
*/
class Complex implements Cloneable {
int[] nums = {1,2,3,4,5};
public Object clone() {
try {
return super.clone();
}catch(CloneNotSupportedException cnse) {
System.out.println(cnse.getMessage());
return null;
}
}
int[] getNums() {
return nums;
}
}
class Test {
Complex c1 = new Complex();
Complex makeCopy() {
return (Complex)c1.clone();
}
public static void main(String[] args) {
Test tp = new Test();
Complex c2 = tp.makeCopy();
int[] mycopy = c2.getNums();
mycopy[0] = 5;
System.out.println();
System.out.print("local array: ");
for(int i = 0; i < mycopy.length; i++)
System.out.print(mycopy[i]);
System.out.println();
System.out.print("cloned object: ");
for(int ii = 0; ii < c2.nums.length; ii++)
System.out.print(c2.nums[ii]);
System.out.println();
System.out.print("original object: ");
for(int iii = 0; iii < tp.c1.nums.length; iii++)
System.out.print(tp.c1.nums[iii]);
}
}
Output:
local array: 52345 cloned object: 52345 original object: 52345
So lets change our code to use deep Copy/Cloning.
package com.meritmix.blog.designpatterns.prototype;
/**
* @author Ravi Yadav
* content for MeritMix.com
* blog address: www.meritmix.com
*/
class Complex implements Cloneable {
int[] nums = {1,2,3,4,5};
public Object clone() {
try {
Complex clone = (Complex)super.clone();
clone.nums = this.nums.clone();
return clone;
}catch(CloneNotSupportedException cnse) {
System.out.println(cnse.getMessage());
return null;
}
}
int[] getNums() {
return nums;
}
}
class Test {
Complex c1 = new Complex();
Complex makeCopy() {
return (Complex)c1.clone();
}
public static void main(String[] args) {
Test tp = new Test();
Complex c2 = tp.makeCopy();
int[] mycopy = c2.getNums();
mycopy[0] = 5;
System.out.println();
System.out.print("local array: ");
for(int i = 0; i < mycopy.length; i++)
System.out.print(mycopy[i]);
System.out.println();
System.out.print("cloned object: ");
for(int ii = 0; ii < c2.nums.length; ii++)
System.out.print(c2.nums[ii]);
System.out.println();
System.out.print("original object: ");
for(int iii = 0; iii < tp.c1.nums.length; iii++)
System.out.print(tp.c1.nums[iii]);
}
}
Output:
local array: 52345 cloned object: 52345 original object: 12345
No comments:
Post a Comment