一:相关定义
原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型进行创建新的对象。
二:相关类图和示例
原型模式类图:
原型模式其实就是通过一个对象拷贝出另一个对象,这里分为深拷贝和浅拷贝。在java的Object中,clone默认实现为浅拷贝(:对于基本类型拷贝值,对于其他对象只拷贝引用地址)。当然,你也可以重写父类Object的clone方法,实现自定义的拷贝。
注意:在java中使用clone方法的类,必须实现Cloneable接口,这只是一个标记。否则,在clone时会出现 java.lang.CloneNotSupportedException异常。
下面看一个简历的克隆示例:
public class Resume implements Cloneable{
private String name;
private String sex;
private String age;
public Resume(String name){
this.name = name;
}
public void setPersonalInfo(String sex, String age){
this.sex = sex;
this.age = age;
}
public Resume clone(){
Resume clo = null;
try {
clo = (Resume) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clo;
}
public String toString(){
return String.format("name:%s, sex:%s, age:%s", name, sex, age);
}
}
进行克隆:
Resume resume = new Resume("Vagrant");
resume.setPersonalInfo("女", "26");
System.out.println(resume);
Resume resume1 = resume.clone();
System.out.println(resume1);
System.out.println(resume.getName() == resume1.getName());
结果:
name:Vagrant, sex:女, age:26
name:Vagrant, sex:女, age:26
true
克隆后的resume1中String对象并没有进行新空间的分配创建,而是直接指向了原有的String对象,所以这里就是浅拷贝。
那么如何实现深拷贝呢?网上资料有两种方式:1,递归的在对象的字段中实现clone方法,每次clone都调用对象中字段的clone;2,通过java序列化的方式实现。这里介绍第二种:
public class Resume implements Serializable{
private String name;
private String sex;
private String age;
public Resume(String name){
this.name = name;
}
public void setPersonalInfo(String sex, String age){
this.sex = sex;
this.age = age;
}
public Resume deepClone() throws IOException, ClassNotFoundException {
//将对象写入流中
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
//从流中读取,进行反序列化
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (Resume) oi.readObject();
}
public String toString(){
return String.format("name:%s, sex:%s, age:%s", name, sex, age);
}
public String getName() {
return name;
}
public String getSex() {
return sex;
}
public String getAge() {
return age;
}
}
结果:
name:Vagrant, sex:女, age:26
name:Vagrant, sex:女, age:26
false
参考书籍:《大话设计模式》