java设计模式-原型模式.md

java设计模式-原型模式

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式。在java中,主要就是靠clone来复制对象,所以原型模式还是要先学习一下Cloneable这个接口。

浅克隆和深克隆

java中用基础类型和引用类型。基础类型就是String,Integer这些类型,引用类型就是对象,数组这些。

那简历来说,简历里面有个人信息,和工作经历。个人信息包括姓名,年龄,性别,个人信息属于简历类里面的属性,工作经历则是另外一个类,在简历类里面引用它。

浅克隆就是只复制了个人信息,工作经历由于是引用对象,所以如果只是克隆简历类,则不管复制几个简历,里面的工作经历都只是引用同个对象。所以深克隆就是将工作经经历也进行克隆。下面来看看代码

实现Cloneable接

WorkExperience.java

public class WorkExperience implements Cloneable{
	private String workDate;
	private String company;
	
	@Override
	protected Object clone()  {
		Object object =null;
		try {
			object = super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return object;
	}
	public WorkExperience(String workDate, String company) {
		super();
		this.workDate = workDate;
		this.company = company;
	}
	get和set方法...

Resume.java(简历类)

public class Resume implements Cloneable{
	private String name;
	private String sex;
	private String age;
	
	private WorkExperience workExperience;

	@Override
	protected Object clone()  {
		Resume clone = null ;
		try {
            //对resume克隆
			clone =(Resume)super.clone();
            //对workExperience克隆,如果没有,就是浅克隆
			clone.setWorkExperience((WorkExperience) workExperience.clone());
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return clone;
	}
	
	public Resume(String name, String sex, String age) {
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	get和set方法...

调用

	public static void main(String[] args) {
		Resume prototype = new Resume("小张", "3", "男");
		WorkExperience workExperience = new WorkExperience("1996","company");
		prototype.setWorkExperience(workExperience);
		
		Resume clone1 = (Resume)prototype.clone();
		
		System.out.println(prototype+"\n"+clone1+"\n");
		System.out.println(prototype.getWorkExperience()+"\n"+
		clone1.getWorkExperience());
	}

打印结果

designPattern.prototypePattern.Resume@7852e922
designPattern.prototypePattern.Resume@4e25154f

designPattern.prototypePattern.WorkExperience@70dea4e
designPattern.prototypePattern.WorkExperience@5c647e05

可以看到结果,复制出来的clone1,包括里面的WorkExperience对象都和原来的不一样,实现了深度克隆。

这里的WorkExperience和Resume都实现了Cloneable接口,在克隆resume类的时候对resume和workexperience都进行克隆。

实现Serializable接口

除了Cloneable接口,还可以实现Serializable接口。

WorkExperience.java只需要声明实现接口就好,去掉clone方法,其余不需要变。

public class WorkExperience implements Serializable{}

Resume.java

public class Resume implements Serializable{

	private static final long serialVersionUID = 7260158333965490347L;
	private String name;
	private String sex;
	private String age;
	
	private WorkExperience workExperience;
	
	protected Object clone()  {
		Object object =null;
		try {
			//将对象写入流中
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ObjectOutputStream ooStream = new ObjectOutputStream(bos);
			ooStream.writeObject(this);
			
			//从流中读出对象
			ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
			ObjectInputStream oIStream = new ObjectInputStream(bis);
			object = oIStream.readObject();
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		}
		return object;
	}
	
	public Resume(String name, String sex, String age) {
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
}

调用和打印结果都一样。就不贴出来了。

这里是用序列化(Serialization)方式来实现克隆,可以看到WorkExperience和Resume都实现了Serialization接口。

序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。

猜你喜欢

转载自blog.csdn.net/weixin_43094917/article/details/82928303