一、定义
同一个类的不同对象之间,大部分字段值是相同的,可以在原有对象的基础上进行拷贝,快速生成一个新的对象,这个方式就是原型模式(Prototype Design Pattern).
二、应用场景
- 对象之间相同/相似,创建对象成本比较大,例如初始化时间长,占用CPU太多,或者占用网络资源太多等,需要优化资源。
- 创建一个对象需要繁琐的数据准备或访问权限等,需要提高性能或者提高安全性;
- 系统中大量使用该类对象,且各个调用者都需要给它的属性重新赋值
三、实现方案
3.1 浅克隆
仅复制当前对象,不复制对象中引用的其他对象,需要实现clone()方法。
3.2 深克隆
不仅复制当前对象的基本属性值,也复制属性引用的对象,需要自己实现具体的方法。以下为两种具体的实现方式:
3.2.1 递归拷贝方案
递归拷贝对象,拷贝对象的引用对象,或引用对象的引用对象,直至对象中只有基本属性为止。
3.2.2 序列化方案
将对象进行序列化,然后在进行反序列化。主要有以下两种方案:
1. JDK原生序列化方式
public Object deepCopy(Object obj) {
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
// 反序列化生成一个新的对象
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
2.第三方序列化框架
public Object deepCopy(Object obj) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
String s = mapper.writeValueAsString(obj);
return mapper.readValue(s, Object.class);
}
3.2 两种克隆方式的区别
- 性能: 浅克隆节省时间和空间,但无法拷贝引用对象;深克隆耗费大量的时间和空间,但可以完全拷贝对象,结合实际情况使用。
- 拷贝结果不同。浅克隆仅拷贝基本属性,引用对象不变;深克隆会拷贝出新的引用对象
四、优雅解决方案
- 使用开源组件提供的方案
org.springframework.beans.BeanUtils;
org.apache.commons.beanutils.BeanUtils;
- 一般原型模式是结合工厂模式一起使用。即原型模式创建对象,工厂模式提供对外的访问;
- WriteOnCopy写时复制场景中,原型模式也经常使用。