java 设计模式之原型模式(浅复制深复制)

概念:

原形模式:

原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.

原型模式中的拷贝分为"浅拷贝"和"深拷贝":
浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.
深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.

演示:

package com.dairuijie.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个
对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对。在 Java 中,复制对象是通过 clone()实现的
实现深复制需要实现Serializable 可以序列化 不然没法序列化对象去进行流的输入输出
 * @author DRJYY
 *
 */
public class Prototype implements   Cloneable,Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer age;
	private String name;
	
	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 浅复制
	 */
	@Override
	protected Object clone() throws CloneNotSupportedException {
	/*	Prototype prot = (Prototype) super.clone();
		return prot;*/
		return super.clone();
	}
	
	/**
	 * 深复制
	 * @return
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public Object deepClone() throws IOException, ClassNotFoundException{
		/**
		 *  写入当前对象的二进制流
		 */
		ByteArrayOutputStream bos =  new ByteArrayOutputStream();
		ObjectOutputStream oos =  new ObjectOutputStream(bos);
		oos.writeObject( this );
		
		/**
		 * 写出当前对象二进制流
		 */
		ByteArrayInputStream bis =  new ByteArrayInputStream(bos.toByteArray());
		ObjectInputStream ois;
		ois = new ObjectInputStream(bis);
		return ois.readObject();
	}

	public Prototype(Integer age, String name) {
		this.age = age;
		this.name = name;
	}
	
}

package com.dairuijie.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
 * 学生实体类 除了基本数据类型 同时包括Prototype 引用 方便我们测试结果
 * @author DRJYY
 *
 */
public class Student  implements Cloneable,Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer age;
	private String name;
	private Prototype prototype;
	
	public Prototype getPrototype() {
		return prototype;
	}
	public void setPrototype(Prototype prototype) {
		this.prototype = prototype;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	public Student(Integer age, String name, Prototype prototype) {
		this.age = age;
		this.name = name;
		this.prototype = prototype;
	}
	public Object deepClone() throws IOException, ClassNotFoundException{
		/**
		 *  写入当前对象的二进制流
		 */
		ByteArrayOutputStream bos =  new ByteArrayOutputStream();
		ObjectOutputStream oos =  new ObjectOutputStream(bos);
		oos.writeObject( this );
		
		/**
		 * 写出当前对象二进制流
		 */
		ByteArrayInputStream bis =  new ByteArrayInputStream(bos.toByteArray());
		ObjectInputStream ois;
		ois = new ObjectInputStream(bis);
		return ois.readObject();
	}
}
package com.dairuijie.prototype;

import java.io.IOException;

/**
 * 
 * @author DRJYY
 *
 */
public class ShallowTest {
	public static void main(String[] args) throws ClassNotFoundException, IOException {
		Prototype p = new Prototype(12, "dai");
		Student student = new Student(13, "dai", p);
		Student stu =	(Student) student.deepClone();
		stu.getPrototype().setAge(123);
		stu.setAge(11);
		System.out.println("原始的student的年龄----"+student.getAge());
		System.out.println("克隆对象----"+stu.getAge());
		System.out.println("克隆对象中的p 引用---"+stu.getPrototype().getAge());
		System.err.println("p的对象原始----"+p.getAge());
	}
}


package com.dairuijie.prototype;

public class DeepTest {
	public static void main(String[] args) throws CloneNotSupportedException {
		Prototype p = new Prototype(12, "dai");
		Student student = new Student(13, "dai", p);
		Student stu =	(Student) student.clone();
		stu.getPrototype().setAge(123);
		stu.setAge(11);
		System.out.println("原始的student的年龄----"+student.getAge());
		System.out.println("克隆对象----"+stu.getAge());
		System.out.println("克隆对象中的p 引用---"+stu.getPrototype().getAge());
		System.err.println("p的对象原始----"+p.getAge());
	}
}

图一  :                                                                                  图二:


如图一就是浅复制结果 发现p 的对象年龄没有变化,图二深复制中p 的对象年龄却被身体stu.getPrototype().setAge(123) 改变了。说明深复制将引用对象都复制过来了。也就是对引用类型的成员变量也进行引用对象的复制。


猜你喜欢

转载自blog.csdn.net/qq_29897369/article/details/79234376