原型模式(克隆)

63 阅读2分钟

原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

浅拷贝

  1. 对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行 值传递,也就是将该属性值复制一份给新的对象。
  2. 对于数据类型是引用数据类型的成员变量,比如说成员变 量是某个数组、某个类的对象等,那么浅拷贝会进行引用传 递,也就是只是将该成员变量的引用值(内存地址)复制一 份给新的对象。因为实际上两个对象的该成员变量都指向 同一个实例。在这种情况下,在一个对象中修改该成员变 量会影响到另一个对象的该成员变量值
  3. 前面我们克隆羊就是浅拷贝
  4. 浅拷贝是使用默认的 clone()方法来实现 sheep = (Sheep) super.clone();

深拷贝

  1. 复制对象的所有基本数据类型的成员变量值
  2. 为所有引用数据类型的成员变量申请存储空间,并复制 每个引用数据类型成员变量所引用的对象,直到该对象可 达的所有对象。也就是说,对象进行深拷贝要对整个对象 进行拷贝
  3. 深拷贝实现方式1:重写clone方法来实现深拷贝
  4. 深拷贝实现方式2:通过对象序列化实现深拷贝(推荐)

public Object deepClone() {

	//创建流对象
	ByteArrayOutputStream bos = null;
	ObjectOutputStream oos = null;
	ByteArrayInputStream bis = null;
	ObjectInputStream ois = null;
	
	try {
		
		//序列化
		bos = new ByteArrayOutputStream();
		oos = new ObjectOutputStream(bos);
		oos.writeObject(this); //当前这个对象以对象流的方式输出
		
		//反序列化
		bis = new ByteArrayInputStream(bos.toByteArray());
		ois = new ObjectInputStream(bis);
		DeepProtoType copyObj = (DeepProtoType)ois.readObject();
		
		return copyObj;
		
	} catch (Exception e) {
		// TODO: handle exception
		e.printStackTrace();
		return null;
	} finally {
		//关闭流
		try {
			bos.close();
			oos.close();
			bis.close();
			ois.close();
		} catch (Exception e2) {
			// TODO: handle exception
			System.out.println(e2.getMessage());
		}
	}
	
}