原型模式(ProtoType):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
UML图:
package com.thpin.repository.designpattern;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class PrototypeDemo {
public static void main(String[] args) throws Exception {
ShallowCloneAttribute sca = new ShallowCloneAttribute(1, "attr");
ShallowCloneObject sco = new ShallowCloneObject(1, "a",sca);
ShallowCloneObject sco1 = sco.clone();
System.out.println(sco);
System.out.println(sco1);
sco1.setStr("b");
sco1.getAttr().setAttrStr("b");
System.out.println(sco);
System.out.println(sco1);
DeepCloneAttribute dca = new DeepCloneAttribute(10, "A");
DeepCloneObject dco = new DeepCloneObject(10, "A", dca);
DeepCloneObject dco1 = dco.deepClone();
System.out.println(dco);
System.out.println(dco1);
dco1.setStr("B");
dco1.getAttr().setAttrStr("B");
System.out.println(dco);
System.out.println(dco1);
}
}
/*
* 浅克隆,实现Cloneable
*/
class ShallowCloneObject implements Cloneable {
private int n;
private String str;
private ShallowCloneAttribute attr;
public ShallowCloneObject(int n, String str, ShallowCloneAttribute attr) {
this.n = n;
this.str = str;
this.attr = attr;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public ShallowCloneAttribute getAttr() {
return attr;
}
public void setAttr(ShallowCloneAttribute attr) {
this.attr = attr;
}
@Override
public String toString() {
return "ShallowCloneObject [n=" + n + ", str=" + str + ", attr=" + attr + "]";
}
public ShallowCloneObject clone() {
Object obj = null;
try {
obj = super.clone();
return (ShallowCloneObject) obj;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
/*
* 浅克隆属性
*/
class ShallowCloneAttribute implements Cloneable {
private int attrN;
private String attrStr;
public ShallowCloneAttribute(int attrN, String attrStr) {
super();
this.attrN = attrN;
this.attrStr = attrStr;
}
public int getAttrN() {
return attrN;
}
public void setAttrN(int attrN) {
this.attrN = attrN;
}
public String getAttrStr() {
return attrStr;
}
public void setAttrStr(String attrStr) {
this.attrStr = attrStr;
}
@Override
public String toString() {
return "ShallowCloneAttribute [attrN=" + attrN + ", attrStr=" + attrStr + "]";
}
public ShallowCloneAttribute clone() {
Object obj = null;
try {
obj = super.clone();
return (ShallowCloneAttribute) obj;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
/*
* 深克隆,实现Serializable。
* 用序列化流重新生成对象
*/
class DeepCloneObject implements Serializable {
private static final long serialVersionUID = 1519509451211402382L;
private int n;
private String str;
private DeepCloneAttribute attr;
public DeepCloneObject(int n, String str, DeepCloneAttribute attr) {
this.n = n;
this.str = str;
this.attr = attr;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public DeepCloneAttribute getAttr() {
return attr;
}
public void setAttr(DeepCloneAttribute attr) {
this.attr = attr;
}
@Override
public String toString() {
return "DeepCloneObject [n=" + n + ", str=" + str + ", attr=" + attr + "]";
}
public DeepCloneObject deepClone() throws IOException, ClassNotFoundException {
// 将对象写入流中
ByteArrayOutputStream bao = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bao);
oos.writeObject(this);
// 将对象从流中取出
ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (DeepCloneObject) ois.readObject();
}
}
/*
* 深克隆属性
*/
class DeepCloneAttribute implements Serializable {
private static final long serialVersionUID = 4073693486556953564L;
private int attrN;
private String attrStr;
public DeepCloneAttribute(int attrN, String attrStr) {
this.attrN = attrN;
this.attrStr = attrStr;
}
public int getAttrN() {
return attrN;
}
public void setAttrN(int attrN) {
this.attrN = attrN;
}
public String getAttrStr() {
return attrStr;
}
public void setAttrStr(String attrStr) {
this.attrStr = attrStr;
}
@Override
public String toString() {
return "DeepCloneAttribute [attrN=" + attrN + ", attrStr=" + attrStr + "]";
}
}
结果:
ShallowCloneObject [n=1, str=a, attr=ShallowCloneAttribute [attrN=1, attrStr=attr]]
ShallowCloneObject [n=1, str=a, attr=ShallowCloneAttribute [attrN=1, attrStr=attr]]
ShallowCloneObject [n=1, str=a, attr=ShallowCloneAttribute [attrN=1, attrStr=b]]
ShallowCloneObject [n=1, str=b, attr=ShallowCloneAttribute [attrN=1, attrStr=b]]
DeepCloneObject [n=10, str=A, attr=DeepCloneAttribute [attrN=10, attrStr=A]]
DeepCloneObject [n=10, str=A, attr=DeepCloneAttribute [attrN=10, attrStr=A]]
DeepCloneObject [n=10, str=A, attr=DeepCloneAttribute [attrN=10, attrStr=A]]
DeepCloneObject [n=10, str=B, attr=DeepCloneAttribute [attrN=10, attrStr=B]]
观察结果中的红字,不难发现浅克隆只能真正考基本数据类型和String,而引用类型还是原来的,前后两个对象指向相同的地址,一变都变。而深克隆实现了所有类型的拷贝,拷贝前后的两个对象除了所属类型相同值相同,没有内存地址上的关联。