1.概念
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效;或者创建值相等,只是命名不一样的同类数据。
2.原型模式的UML类图
3.Java中对象的克隆
(1)为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
(2)在派生类中覆盖基类的clone()方法,并声明为public。
(3)在派生类的clone()方法中,调用super.clone()。
(4)在派生类中实现Cloneable接口。
4.在Java中,clone()方法是浅复制。
浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
可以利用串行化来做深复制,所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象。
5.简历模板案例
/**
* 简历类
*
*/
public class Resume implements Serializable,Cloneable {
/**
*
*/
private static final long serialVersionUID = 8614140644886700330L;
private String name;
private String sex;
private Integer age;
private WorkExperience work;
public Resume(String name){
this.name = name;
work = new WorkExperience();
}
//设置个人信息
public void setPersonalInfo(String sex, Integer age){
this.sex = sex;
this.age = age;
}
//设置工作经历
public void setWorkExperience(String workDate,String company){
work.setWorkDate(workDate);
work.setCompany(company);
}
//显示
public void display(){
System.out.println(String.format("%s %s %s", name,sex,age));
System.out.println(String.format("工作经历:%s %s", work.getWorkDate(), work.getCompany()));
}
//浅复制
public Object clone(){
Object obj = null;
try {
obj = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return obj;
}
//深复制
public Object 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 (oi.readObject());
}
}
--------------------------------------------------------------------------------
/**
* 工作经历类
*
*/
public class WorkExperience implements Serializable {
private static final long serialVersionUID = -5461562344310808271L;
private String workDate;
public String getWorkDate() {
return workDate;
}
public void setWorkDate(String workDate) {
this.workDate = workDate;
}
private String company;
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
}
--------------------------------------------------------------------------------
/**
* 客户端调用
*
*/
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, IOException {
Resume a = new Resume("大鸟");
a.setPersonalInfo("男", 29);
a.setWorkExperience("1998-2000", "xx公司");
//浅复制
Resume b = (Resume)a.clone();
b.setPersonalInfo("男", 25);
b.setWorkExperience("1998-2006", "yy公司");
a.display();
b.display();
// 运行结果:a和b的WorkExperience的引用值是一样的,改变b的WorkExperience值,a也会变化
// 大鸟 男 29
// 工作经历:1998-2006 yy公司
// 大鸟 男 25
// 工作经历:1998-2006 yy公司
// demo2
Resume c = new Resume("大鸟");
c.setPersonalInfo("男", 29);
c.setWorkExperience("1998-2000", "xx公司");
//深复制
Resume d = (Resume)c.deepClone();
d.setPersonalInfo("男", 25);
d.setWorkExperience("1998-2006", "yy公司");
c.display();
d.display();
// 运行结果:a和b的WorkExperience的引用值是不同的
// 大鸟 男 29
// 工作经历:1998-2000 xx公司
// 大鸟 男 25
// 工作经历:1998-2006 yy公司
}
}