大话设计模式的学习(原型模式)

先看一段代码:

//简历类
public class Resume{
	private String name;
	private String age;
	private String sex;
	private String timeArea;
	private String company;
	public Resume (String name){
		this.name = name;
	}
	//设置个人信息
	public void setPersonalInfo(String age,String sex){
		this.age= age;
		this.sex= sex;
	}
	//设置工作经历
	public void setWorkExperience(String timeArea ,String company){
		this.timeArea = timeArea;
		this.company = company;
	}	
	//显示方法
	public void Show(){
		System.out.println(this.name+"   "+this.age+"   "+this.sex);
		System.out.println(this.timeArea+"   "+this.company);
	}

}
public class StartMain {
    public static void main(String[] args) throws Exception {
        Resume a = new Resume("王小明");
		a.setPersonalInfo("21", "男");
		a.setWorkExperience("2018", "百度");	
		Resume b = a;
		a.setPersonalInfo("22", "男");
		b.setPersonalInfo("24", "女");
		a.Show();
		b.Show();
    }
}

而打印出来的结果却是:

王小明   24   女
2018   百度
王小明   24   女
2018   百度

从结果可以看到,a和b对象中的值是完全一样的,可明明在代码中给a和b设置了不同的值,结果为什么一样?

Resume b = a这句代码其实是传的引用,而不是传值,所以不管a/b中哪个更改了值,都会修改另一个的值。

那么如何复制一份简历,并去修改自身的值呢?(这里忽略重新new的方式)

原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建对象的细节。

代码修改后:

public class Resume implements Cloneable {
	private String name;
	private String age;
	private String sex;
	private String timeArea;
	private String company;
	public Resume (String name){
		this.name = name;
	}
	//设置个人信息
	public void setPersonalInfo(String age,String sex){
		this.age= age;
		this.sex= sex;
	}
	//设置工作经历
	public void setWorkExperience(String timeArea ,String company){
		this.timeArea = timeArea;
		this.company = company;
	}
	public Object Clone() throws Exception {
		return this.clone();
	}	
	//显示方法
	public void Show(){
		System.out.println(this.name+"   "+this.age+"   "+this.sex);
		System.out.println(this.timeArea+"   "+this.company);
	}
}
public class StartMain {
	public static void main(String[] args) throws Exception {	
		Resume a = new Resume("王小明");
		a.setPersonalInfo("21", "男");
		a.setWorkExperience("2018", "百度");	
		Resume b = (Resume) a.Clone();
		a.setPersonalInfo("22", "男");
		b.setPersonalInfo("24", "女");
		a.Show();
		b.Show();		
	}
}

查看结果:

王小明   22   男
2018   百度
王小明   24   女
2018   百度

浅复制与深复制:

clone()方法:如果字段是值类型的,则对该字段进行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,所以,原始对象和其复本引用同一个对象。

浅复制:被复制对象的所有变量都含有与原来的对象一样的值,而所有的对其他对象的引用都仍指向原来的对象。

深复制:把引用对象的变量指向复制过的新变量,而不是原有的被引用的对象。

上代码解释:

//工作经历类
public class WorkExperience {
	public String workDate;
	public String company;
	public String getWorkDate() {
		return workDate;
	}
	public void setWorkDate(String workDate) {
		this.workDate = workDate;
	}
	public String getCompany() {
		return company;
	}
	public void setCompany(String company) {
		this.company = company;
	}
	
}

public class Resume implements Cloneable {
	private String name;
	private String age;
	private String sex;
	private WorkExperience work;
	public Resume (String name){
		this.name = name;
		work = new WorkExperience();
	}
	//设置个人信息
	public void setPersonalInfo(String age,String sex){
		this.age= age;
		this.sex= sex;
	}
	//设置工作经历
	public void setWorkExperience(String workDate ,String company){
		work.workDate = workDate;
		work.company = company;
	}
	public Object Clone() throws Exception {
		return this.clone();
	}	
	//显示方法
	public void Show(){
		System.out.println(this.name+"   "+this.age+"   "+this.sex);
		System.out.println(work.workDate+"   "+work.company);
	}
}

public class StartMain {
	public static void main(String[] args) throws Exception {	
		Resume a = new Resume("王小明");
		a.setPersonalInfo("21", "男");
		a.setWorkExperience("2018", "百度");	
		Resume b = (Resume) a.Clone();
		b.setPersonalInfo("24", "女");
		b.setWorkExperience("2016", "阿里");
		a.Show();
		b.Show();		
	}
}

打印结果:

王小明   21   男
2016   阿里
王小明   24   女
2016   阿里

从结果可以看出,复制出的对象b和原对象a在设置值类型的变量时,各自修改各自的值,而对于引用类型(WorkExperience)的修改,不管a和b哪个修改了,都会修改另一个对象的值。

而我想要的是克隆后,新的对象无论怎么修改值,包括引用对象的值,都与之前的没有关系,该如何做到?

深复制的实现:

//工作经历类
public class WorkExperience implements Cloneable {
	public String workDate;
	public String company;
	public String getWorkDate() {
		return workDate;
	}
	public void setWorkDate(String workDate) {
		this.workDate = workDate;
	}
	public String getCompany() {
		return company;
	}
	public void setCompany(String company) {
		this.company = company;
	}
	
	public Object Clone() throws Exception {
		return this.clone();
	}
}

public class Resume implements Cloneable {
	private String name;
	private String age;
	private String sex;
	private WorkExperience work;
	public Resume (String name){
		this.name = name;
		work = new WorkExperience();
	}
	private Resume(WorkExperience work) throws Exception {
		this.work = (WorkExperience) work.Clone();
	}
	//设置个人信息
	public void setPersonalInfo(String age,String sex){
		this.age= age;
		this.sex= sex;
	}
	//设置工作经历
	public void setWorkExperience(String workDate ,String company){
		work.workDate = workDate;
		work.company = company;
	}
	public Object Clone() throws Exception {
		Resume resume = new Resume(this.work);
		resume.name=this. name;
		resume.age=this. age;
		resume.sex=this. sex;
		return resume;	
	}	
	//显示方法
	public void Show(){
		System.out.println(this.name+"   "+this.age+"   "+this.sex);
		System.out.println(work.workDate+"   "+work.company);
	}
}

public class StartMain {
	public static void main(String[] args) throws Exception {	
		Resume a = new Resume("王小明");
		a.setPersonalInfo("21", "男");
		a.setWorkExperience("2018", "百度");	
		Resume b = (Resume) a.Clone();
		b.setPersonalInfo("24", "女");
		b.setWorkExperience("2016", "阿里");
		a.Show();
		b.Show();		
	}
}

结果如下:

王小明   21   男
2018   百度
王小明   24   女
2016   阿里

这样就达到了深复制的效果,也就是原型模式的深复制。

 

 

 


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值