Jianwoo中的设计模式(6) — 原型模式

前言

什么是原型模式呢,就是通过已有对象实例去创建同类型对象并且使用已有对象实例数据的拷贝来创建新对象,说简单点就是克隆
克隆一般有两种,一种是浅克隆,另一种是深克隆。什么是浅克隆,就是通过实现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啦,这就是深克隆

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • JAVA序列化机制的深入研究 对象序列化的最主要的用处就是在传递,和保存对象(object)的时候,保证对象的完整...
    时待吾阅读 10,920评论 0 24
  • 定义 原型模式属于对象的创建模式。通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建...
    步积阅读 1,372评论 0 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,923评论 18 139
  • 1大同小异的工作周报 Sunny软件公司一直使用自行开发的一套OA (Office Automatic,办公自动化...
    justCode_阅读 1,190评论 0 3
  • 人处在某挫折中的时候,一味的悲伤、萎靡不振就等于在这个伤口上 再撒把盐。心态要及时的调整。四个字是那个时候的体会“...
    Ruuush阅读 187评论 0 0