设计模式笔记————原型模式

原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

java 可以通过实现 Cloneable 接口重写 clone 方法来实现原型模式。

原型模式不用重新初始化对象,而是动态的获得对象运行时的状态,隐藏了对象创建的细节,对性能大大提高。

clone 方法复制的过程是这样的,如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,因此原始对象及其副本引用同一对象。

浅复制示例:

public class Resume implements Cloneable {

	private String name;
	private String age;
	private String sex;
	private WorkExperience workExperience;
	
	public Resume(String name) {
		this.name = name;
		workExperience = new WorkExperience();
	}
	
	public void setPersonalInfo(String age, String sex) {
		this.age = age;
		this.sex = sex;
	}
	
	public void setWorkExperience(String timeArea, String company) {
		workExperience.setTimeArea(timeArea);
		workExperience.setCompany(company);
	}
	
	public void Display() {
		System.out.println(name + age + sex);
		System.out.println(workExperience.getTimeArea() + workExperience.getCompany());
	}
	
	public Resume clone() throws CloneNotSupportedException {
		return (Resume) super.clone();
	}
}
//该类有两个字段和get、set方法
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 static void main(String[] args) throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		Resume aResume = new Resume("人员A");
		aResume.setPersonalInfo("1岁", "m");
		aResume.setWorkExperience("2010-2020", "A公司");

		Resume bResume = aResume.clone();
		bResume.setPersonalInfo("2岁", "w");
		bResume.setWorkExperience("2020-2030", "B公司");
		bResume.Display();
		aResume.Display();
	}

输出:

人员A  2岁  w
2020-2030  B公司
人员A  1岁  m
2020-2030  B公司

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

修改为深复制:

//实现 Cloneable 接口
public class WorkExperience implements Cloneable {
	...
	//其余方法属性不变
	...
	public WorkExperience clone() throws CloneNotSupportedException {
		return (WorkExperience) super.clone();
	}
}
public class Resume implements Cloneable {
	...
	//其余方法属性不变
	...
	public Resume clone() throws CloneNotSupportedException {
		Resume aResume = (Resume) super.clone();
		aResume.workExperience = workExperience.clone();
		return aResume;
	}
}

测试用例输出:

人员A  2岁  w
2020-2030  B公司
人员A  1岁  m
2010-2020  A公司

需要注意的是:

数组的clone,仅仅复制的是数组中的元素,即若数组中元素为引用类型,仅仅复制引用。
若clone的对象中含有链表,则应单独对链表进行循环复制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值