您的位置:首页 > 其它

七、原型模式(深浅克隆)

2013-09-11 13:59 387 查看
类似“影之分身术”的东西,以“鸣人”为原型,复制1000份出来,群殴之……

在初始化信息不发生变化的情况下,克隆是最好的办法。既隐藏了对象创建的细节,又对性能大大的提高——不用重新初始化对象,而是动态地获得对象运行时的状态。

——摘自《大话设计模式》

提到原型模式,就不得不提深浅克隆。两者都是完成对原型的复制,而区别在于对其引用对象的复制情况:

浅复制:仅仅复制原型,而对其他对象的引用仍指向原有对象,即不复制原型的引用对象。

深复制:把原型和原型的引用对象都复制了一遍。

一、浅复制

以简历复制为例,进行代码演示

①、原型#########################################

/**
*	原型,个人简历,实现Cloneable接口
*/
public class Resume implements Cloneable{
private String name;
private Integer age;
private Character sex;
private WorkExperience work; //工作简历的引用

//初始化姓名
public Resume(String name,WorkExperience work){
this.name = name;
this.work = work;
}

//设置个人信息
public void setPersonalInfo(Character sex,Integer age){
this.sex = sex;
this.age = age;
}

//设计工作经历
public void setWorkExperience(String timeArea,String company){
work.setTimeArea(timeArea);
work.setCompany(company);
}

public void display(){
System.out.println("个人信息:"+name+"\t"+age);
System.out.println("工作经历:"+work.getTimeArea()+"\t"+work.getCompany());
}

@Override
public Object clone(){ //浅克隆,直接调用Object的clone方法
Object ob = null;
try {
ob = super.clone();
} catch (Exception e) {
e.printStackTrace();
}
return ob;
}
}


②、原型的引用类#########################################

/**
*	工作简历
*/
public class WorkExperience{
private String timeArea; //时间段
private String company;  //所在公司

public String getTimeArea() {
return timeArea;
}
public void setTimeArea(String timeArea) {
this.timeArea = timeArea;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
}


测试方法:

public class Test {
public static void main(String[] args) throws Exception {
WorkExperience work = new WorkExperience(); //工作简历实例化

Resume a = new Resume("张三",work); //张三的第一份简历
a.setPersonalInfo('男', 23);
a.setWorkExperience("1996-1999", "IBM");

Resume b = (Resume) a.clone();	//张三的第二份简历,工作经验有所改动
b.setWorkExperience("2000-2002", "Microsoft");

System.out.println("第一份简历:");
a.display();
System.out.println("\n第二份简历:");
b.display();
}
}

运行结果为:



Ps:并没有达到预期的效果,把第一份简历的工作经验也修改了

二、深复制

实例以串行化的方式进行深复制,需实现Serializable接口:

①、原型#########################################

/**
*	原型,个人简历,实现Cloneable,Serializable接口
*/
public class Resume implements Cloneable,Serializable{
/**
*	……与浅复制相同部分省略……
*/

@Override
public Object clone(){ //以串行化的方式深度克隆
try {
//将对象写到流里
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();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}


②、原型的引用类#########################################

/**
*	工作简历,实现Serializable接口
*/
public class WorkExperience implements Serializable{
/**
*	……与浅复制相同部分省略……
*/
}


再次调用测试方法,运行结果为:



Ps:达到预期的效果,单独修改第二份简历工作经验
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: