设计模式-原型模式
原型模式
使用场景
如果对象的创建成本比较大,同一个类的不同对象之间差别不大(大部分字段都相同),在这种情况下,可以利用已有对象(原型 )进行复制(拷贝)的方式来创建新对象,以达到节省创建时间的目的。这种基于原型来创建对象的方式叫做原型设计模式(Prototype Design Pattern)。
什么是”对象的创建成本比较大“
如果对象中的数据需要经过复杂计算才能得到(排序,计算哈希值),或者需要从RPC,网络,数据库文件系统等非常慢速的IO中读取,这样的对象创建成本就比较大,创建时间长。如果能从一个对象实例中拷贝出来,而不用每次都创建新对象,那么可以节省大量时间。
深拷贝与浅拷贝
浅拷贝
浅拷贝复制对象的索引,不会复制数据。比如在java中,clone对象就是浅拷贝,它只会拷贝对象中的基本数据类型的数据,以及应引用对象的内存地址,不会递归地拷贝引用对象本身。
final HashMap<String, BigObject> obj = (HashMap<String, BigObject>) map.clone();
复制的对象:
可以看到map
的地址值784和 map.clone
得到的obj
的地址值783不一样,但是它们指向的对象是一样的。
深拷贝
相应地,深拷贝会拷贝对象的引用和数据,可以理解为创建一个新的对象。
方法一
所以实现深拷贝的方法之一就是,创建一个新对象,将旧对象的数据完全拷贝进来,包括对象的基本数据类型和引用,然后拷贝引用的对象及其引用....递归下去,直到要拷贝的对象只包含基本数据类型,没有引用对象为止。
方法二
先将对象序列化,然后再反序列化成新的对象。
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大对象的索引,再用深拷贝更新索引指向的对象。