参考《设计模式的艺术软件开发人员内功修炼之道》-刘伟 著
实验目的
原型模式作为创建对象方式的一种,新对象为原型对象的拷贝;分为浅拷贝和深拷贝
实验代码
package PrototypeManager;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
abstract class ShallowCopyAttachment implements Cloneable {
private String name;
private ShallowCopyAttachment subAttach;
public void setName(String name) {
this.name = name;
}
String getName() {
return this.name;
}
public void setAttachment(ShallowCopyAttachment attach) {
subAttach = attach;
}
public ShallowCopyAttachment getAttachment() {
return subAttach;
}
@Override
public ShallowCopyAttachment clone() {
// TODO Auto-generated method stub
Object scAttch = null;
try {
scAttch = super.clone();
return (ShallowCopyAttachment) (scAttch);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
class ShallowCopyAttachmentA extends ShallowCopyAttachment {
public ShallowCopyAttachmentA(){
this.setName("ShallowCopyAttachmentA");
}
}
abstract class DeepCopyAttachment implements Serializable {
private String name;
private DeepCopyAttachment subAttach;
public void setName(String name) {
this.name = name;
}
String getName() {
return this.name;
}
public void setAttachment(DeepCopyAttachment attach) {
subAttach = attach;
}
public DeepCopyAttachment getAttachment() {
return subAttach;
}
/**
*
*/
private static final long serialVersionUID = -1025197199068560319L;
/**
*
*/
//private static final long serialVersionUID = 1L;
public DeepCopyAttachment 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 (DeepCopyAttachment)ois.readObject();
}
}
class DeepCopyAttachmentA extends DeepCopyAttachment {
/**
*
*/
private static final long serialVersionUID = -4458940275684875744L;
public DeepCopyAttachmentA(){
this.setName("DeepCopyAttachmentA");
}
}
class AttachmentManager {
private HashMap<String, ShallowCopyAttachment> scHashMap;
private HashMap<String, DeepCopyAttachment> dcHashMap;
private AttachmentManager() {
scHashMap = new HashMap<String, ShallowCopyAttachment>();
dcHashMap = new HashMap<String, DeepCopyAttachment>();
}
static class ManagerBuilder {
static final AttachmentManager attach = new AttachmentManager();
}
public static AttachmentManager getAttachmentManager() {
return ManagerBuilder.attach;
}
public void addShallowCopyAttachment(String key, ShallowCopyAttachment scAttach) {
scHashMap.put(key, scAttach);
}
public ShallowCopyAttachment getShallowCopyAttachment(String key) {
return ((ShallowCopyAttachment) (scHashMap.get(key))).clone();
}
public void addDeepCopyAttachment(String key, DeepCopyAttachment dcAttach) {
dcHashMap.put(key, dcAttach);
}
public DeepCopyAttachment getDeepCopyAttachment(String key) {
try {
DeepCopyAttachment a = ((DeepCopyAttachment) (dcHashMap.get(key))).deepClone();
//System.out.println(a.getName() + ":" + a.getAttachment());
return a;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public class CloneTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
AttachmentManager attach = AttachmentManager.getAttachmentManager();
ShallowCopyAttachment scAttach = new ShallowCopyAttachmentA();
ShallowCopyAttachment subSCAttach = new ShallowCopyAttachmentA();
subSCAttach.setAttachment(null);
scAttach.setAttachment(subSCAttach);
DeepCopyAttachment dcAttach = new DeepCopyAttachmentA();
DeepCopyAttachment subDCAttach = new DeepCopyAttachmentA();
subDCAttach.setAttachment(null);
dcAttach.setAttachment(subDCAttach);
attach.addShallowCopyAttachment("scAttach", scAttach);
attach.addDeepCopyAttachment("dcAttach", dcAttach);
ShallowCopyAttachment scAttach1 = attach.getShallowCopyAttachment("scAttach");
DeepCopyAttachment dcAttach1 = attach.getDeepCopyAttachment("dcAttach");
System.out.println("dcAttach1 = " + dcAttach1);
System.out.println(scAttach.getName() + " ; " + scAttach.getAttachment());
System.out.println(scAttach1.getName() + " ; " + scAttach1.getAttachment());
System.out.println(scAttach == scAttach1);
System.out.println(scAttach.getAttachment() == scAttach1.getAttachment());
System.out.println(dcAttach.getName() + " ; " + dcAttach.getAttachment());
System.out.println(dcAttach1.getName() + " ; " + dcAttach1.getAttachment());
System.out.println(dcAttach == dcAttach1);
System.out.println(dcAttach.getAttachment() == dcAttach1.getAttachment());
}
}
结果输出
dcAttach1 = PrototypeManager.DeepCopyAttachmentA@4eec7777
ShallowCopyAttachmentA ; PrototypeManager.ShallowCopyAttachmentA@3b07d329
ShallowCopyAttachmentA ; PrototypeManager.ShallowCopyAttachmentA@3b07d329
false
true
DeepCopyAttachmentA ; PrototypeManager.DeepCopyAttachmentA@28d93b30
DeepCopyAttachmentA ; PrototypeManager.DeepCopyAttachmentA@41629346
false
false
总结
- 浅拷贝基于object中的clone实现;深拷贝通过serializable方式实现
- 基于serialize的深拷贝要求对象的类型所在继承树上的每一个类都要serializable