创建型 原型模式

0 阅读3分钟

原型模式的两种实现方式:深拷贝和浅拷贝

原型模式的原理与应用

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

原型模式的两种实现方法

原型模式有两种实现方法,深拷贝和浅拷贝。

浅拷贝只会复制对象中基本数据类型数据和引用对象的内存地址,不会递归地复制引用对象,以及引用对象的引用对象……而深拷贝得到的是一份完完全全独立的对象。所以,深拷贝比起浅拷贝来说,更加耗时,更加耗内存空间。如果要拷贝的对象是不可变对象,浅拷贝共享不可变对象是没问题的,但对于可变对象来说,浅拷贝得到的对象和原始对象会共享部分数据,就有可能出现数据被修改的风险,也就变得复杂多了。

 

浅拷贝:浅拷贝的实质定义:只拷贝基本数据类型和引用类型的地址,不拷贝引用对象本身,不会在堆内存中重新创建对象。

Object 类的 clone() 方法执行的是浅拷贝。它只会拷贝对象中的基本数据类型的数据(比如,int、long),以及引用对象(SearchWord)的内存地址,不会递归地拷贝引用对象本身。

截图.png

 

深拷贝:实现方式有两种,

第一种方法:递归拷贝对象、对象的引用对象以及引用对象的引用对象……直到要拷贝的对象只包含基本数据类型数据,没有引用对象为止。

第二种方法:先将对象序列化,然后再反序列化成新的对象。

截图.png

浅拷贝和深拷贝:关键看引用的物理地址有没有发生变化,如果没有变化则是浅拷贝,发生变化就是深拷贝,也就是看这个拷贝有没有在堆中创建出来对象,没有创建新的对象,只是创建了一个对象引用则是浅拷贝,如果在堆中创建出了新的对象,则是深拷贝。

//map中的value存的是对象的引用,也就是一个物理地址

HashMap<Integer, Person> copyMap = new HashMap<>();

copyMap.put(1001, new Person("li"));

copyMap.put(1002, new Person("wang"));

 

//object的clone都是浅拷贝,浅拷贝只会拷贝基本数据类型和对象的引用,新集合中的value跟

//老集合中的value是相同的,指向同一个内存对象,所以此时更改Person对象中的内容,两边都会更改

HashMap<Integer, Person> lightCopy = (HashMap<Integer, Person>) copyMap.clone();

 

//深拷贝 实现方式 先将对象序列化,然后再反序列化成新的对象。

try {

HashMap<Integer, Person> deepCopyMap = (HashMap<Integer, Person>) deepCopy(copyMap);

} catch (Exception e) {

e.printStackTrace();

}

 

 

public Object deepCopy(Object object) {

Object copyObject = null;

try {

ByteArrayOutputStream bo = new ByteArrayOutputStream();

ObjectOutputStream oo = new ObjectOutputStream(bo);

oo.writeObject(object);

ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());

ObjectInputStream oi = new ObjectInputStream(bi);

object = oi.readObject();

} catch (Exception e) {

e.printStackTrace();

}

return copyObject;

}