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

 类似“影之分身术”的东西,以“鸣人”为原型,复制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:达到预期的效果,单独修改第二份简历工作经验

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值