• 原型模式


    一、概念

    原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。(创建型模式。简单来说,就是用于复制对象)

    在Spring中,原型模式应用得非常广泛。例如 scope=“prototype”,我们经常用的JSON.parseObject()也是一种原型模式。

    我们拿电脑中的复制粘贴的例子来演示一下原型模式: 

    上面这张图已经很明显了,我们首先需要一个文件,该文件一定要有可以被克隆的功能,那么我们创建这个文件后,就可以通过它克隆无数个。

    下面是原型模式的类结构图:

    二、适用场景

    • 类初始化消耗资源较多
    • new产生的一个对象需要非常繁琐的过程(数据准备、访问权限等)
    • 构造方法比较复杂
    • 循环体中生产大量对象时

    三、模拟原型模式

    ① 先声明一个克隆自身的原型Prototype接口:

    ② 创建具体需要克隆的对象ConcretePrototype:

    ③ 定义一个Client类,用于测试克隆对象:

    上面实际上,把new用代码隐藏了,本质上对象的产生还是靠new产生的,只是耐看了一些,具备了原型模式的形态,但产生的对象并不能直接复制对象的当前运行状态(每拷贝一次对象,需要走一次构造方法),所以需要做一些改进。

    四、真正原型模式

    • 只有实现了Cloneable这个接口的类才可以被拷贝
    • 拷贝得到的是一个新的对象,但是这个新对象的内容是拷贝对象的当前运行时内容
    • 在拷贝对象的过程中,没有调用构造方法(new的时候,JVM要走一趟类加载流程,这个流程非常麻烦,会调用构造方法,再把最后生成的对象放到堆中。而Object类的clone()方法原理:JVM从堆内存中以二进制流的方式进行拷贝,重新分配一个内存块,将对象当前内存状态拷贝到新开辟的内存中)
    • 拷贝分为浅拷贝深拷贝,主要区别在于是否支持对象引用类型的成员变量的拷贝

    1、浅拷贝:只会拷贝基本数据类型(也包括String),对于对象属性只拷贝其中的引用地址。

    例子:① 定义一个Student类,实现Cloneable接口,重写clone()方法。

    ② 测试代码:

    ③ 运行结果:

    分析:从测试结果可以看出,String[]对象没有被拷贝,拷贝的只是对象引用的地址。因此,如果我们修改任意一个对象类型的成员变量的属性值,比如上图中的hobbies值,则所有拷贝的hobbies值都会改变,这就是浅拷贝。

    下面这张图,对象引用的地址指向堆内存中的对象实例:

    2、深拷贝:不仅能够拷贝基本数据类型,还能拷贝对象引用类型(包括数组、容器、引用对象等)。

    例子:① 还是原来的Student类,现在对clone()方法中的逻辑做一些修改。

    ② 测试代码:

    ③ 运行结果:

    分析:从测试结果可以看出,String[]对象在内存中被拷贝。因此,如果要实现深拷贝,必须将原型中的数组、容器对象、引用对象等另行拷贝(这些引用对象也要实现Cloneable接口)。

    五、拷贝破坏单例模式

    提问:如果我们深拷贝的目标对象是单例对象,那意味着,深拷贝就会破坏单例,怎么办?

    实际上防止拷贝破坏单例的解决思路很简单:

    ① 禁止深拷贝即可

    ② 单例类不实现Cloneable接口

    ③ 如果非要实现Cloneable接口,那么可以重写clone()方法,在方法中返回单例对象即可,如下:

    六、在源码中的应用

    我们常用的ArrayList就实现了Cloneable接口,重写clone()方法,源码如下:

  • 相关阅读:
    潜水一年,然后回来
    【搬运】Visual Studio vs2017 vs2019 中文离线安装包下载,替代ISO镜像
    Re0:在 .NetCore中 EF的基本使用
    Re0:在.NetCore 中Dapper的基本用法
    jdadjkgh.txt
    Android Studio打包出来的安装包是非正式发布版本
    Android Studio生成开发调试版(Debug)和正式发布版(Release)的安装包
    【unity-2】coroutine
    【ugui-1】RectTransformUtility
    [ps笔记]快捷键、快捷方式
  • 原文地址:https://www.cnblogs.com/ZekiChen/p/12492959.html
Copyright © 2020-2023  润新知