前言
什么是原型模式呢,就是通过已有对象实例去创建同类型对象并且使用已有对象实例数据的拷贝来创建新对象,说简单点就是克隆
克隆一般有两种,一种是浅克隆,另一种是深克隆。什么是浅克隆,就是通过实现Cloneable接口,然后重写克隆方法把当前类的基本对象重新赋值到新对象的形式,也叫表面克隆,这种克隆适合参数不多层次不深的对象,但是对于那种对象内还有对象,层次内对象还有别的对象的情况,浅克隆很明显并不合适,这篇文章主要讲深克隆所代表的原型模式,以及克隆中所遇到的一些问题
简物中的应用场景
在简物性能优化这篇文章中,提到了详情界面的数据和UI在不可见时候要释放资源,以节省内存资源,这样即使打开几十个上百个界面,也是如丝滑一般顺畅,当我们返回界面时就要重新加载资源,那我们为了保护原始对象不受界面回收的影响可以将原始数据克隆一份作为母体数据,这样不管什么时候返回我们都拿原始数据的克隆对象去恢复界面,那我们如何实现这种深克隆,这里要用到序列化和反序列化
序列化和反序列化
概念:在Java中把对象转换为字节序列的过程叫做序列化,反过来把字节序列转化成对象的过程就叫反序列化
注意:凡是需要被序列化的对象,不管是直接对象还是包含对象,均需要实现Serializable接口
通过序列化我们可以把对象序列化到本地也可以序列化到内存,根据不同的场景采取不同的做法,简物中的克隆是将对象序列化到内存,在实体类中,我们只要随意定义一个方法写序列化和反序列化方法即可,这里是clone方法
public static class SaleDetail implements Serializable{
int goods_id;
String image;
String title;
String describe;
String price;
String discount_price;
List<Tag> tags;
List<Skus> skus;
List<Products> products;
List<LinkGoods> link_goods;
String[] images;
int is_mark;
public void clear(){
image = null;
title = null;
describe = null;
price = null;
discount_price = null;
tags.clear();
skus.clear();
products.clear();
link_goods.clear();
tags = null;
skus = null;
products = null;
link_goods = null;
images = null;
}
@Override
public SaleDetail clone(){
SaleDetail saleDetail = null;
try{
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(SaleDetail.this);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
saleDetail = (SaleDetail) objectInputStream.readObject();
}catch (IOException|ClassNotFoundException e){
}
return saleDetail;
}
...
}
看到没,这就是序列化对象到内存的过程,是不是很简单,没有什么复杂的地方,甚至都不需要我多说了,聪明的你应该能理解
那如果有时候有些对象引用我们不需要序列化怎么办呢,比如对象里面有一个Context引用,那这个时候我们可以用transient修饰这个对象,这个对象就会被排除在序列化之外
transient Context context;
最后的调用就是
@Override
public void getSaleDetailSucess(SaleDetailBean.SaleDetail saleDetail) {
if(saleDetail == null){
return;
}
this.mSaleDetail = saleDetail;
this.mSaleDetailCopy = saleDetail.clone();
...
}
然后拿mSaleDetailCopy去操作就不会影响到saleDetail啦,这就是深克隆