Loading

设计模式-原型模式

原型模式

使用场景

如果对象的创建成本比较大,同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,可以利用已有对象(原型 )进行复制(拷贝)的方式来创建新对象,以达到节省创建时间的目的。这种基于原型来创建对象的方式叫做原型设计模式(Prototype Design Pattern)。

什么是”对象的创建成本比较大“

如果对象中的数据需要经过复杂计算才能得到(排序,计算哈希值),或者需要从RPC,网络,数据库文件系统等非常慢速的IO中读取,这样的对象创建成本就比较大,创建时间长。如果能从一个对象实例中拷贝出来,而不用每次都创建新对象,那么可以节省大量时间。

深拷贝与浅拷贝

浅拷贝

浅拷贝复制对象的索引,不会复制数据。比如在java中,clone对象就是浅拷贝,它只会拷贝对象中的基本数据类型的数据,以及应引用对象的内存地址,不会递归地拷贝引用对象本身。

img

final HashMap<String, BigObject> obj = (HashMap<String, BigObject>) map.clone();

复制的对象:

image-20210411154159132

可以看到map的地址值784和 map.clone得到的obj的地址值783不一样,但是它们指向的对象是一样的。

深拷贝

相应地,深拷贝会拷贝对象的引用和数据,可以理解为创建一个新的对象。

img

方法一

所以实现深拷贝的方法之一就是,创建一个新对象,将旧对象的数据完全拷贝进来,包括对象的基本数据类型和引用,然后拷贝引用的对象及其引用....递归下去,直到要拷贝的对象只包含基本数据类型,没有引用对象为止。

方法二

先将对象序列化,然后再反序列化成新的对象。

 public Object deepCopy(Object object) {
  ByteArrayOutputStream bo = new ByteArrayOutputStream();
  ObjectOutputStream oo = new ObjectOutputStream(bo);
  oo.writeObject(object);
  
  ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
  ObjectInputStream oi = new ObjectInputStream(bi);
  
  return oi.readObject();
}

浅拷贝+深拷贝

深拷贝要比浅拷贝耗时、耗内存。有时我们可以利用浅拷贝+深拷贝来实现一些场景。比如可以浅拷贝来copy大对象的索引,再用深拷贝更新索引指向的对象。

posted @ 2021-11-20 01:03  非凡岁月  阅读(30)  评论(0编辑  收藏  举报