原型模式
原型模式的定义:
是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。(创建性模式)
原型模式的核心在于拷贝原型对象。以系统中已存在的一个对象为原型,直接基于内存二进制流进行拷贝,无需再经历耗时的对象初始化过程(不需要关注创建细节、构造函数),性能提升许多;当构建过程比较耗时时,可以利用已存在的对象作为原型,对其进行克隆。
原型模式主要适用于以下场景:
1、类初始化消耗的资源相对较多。
2、new 产生的一个对象需要非常繁琐的过程(数据准备,访问权限等)。
3、构造函数比较复杂
4、循环体中生产大量的对象时。
在Spring中,原型模式应用得非常广泛。例如 scope = “prototype”,在我们经常用的JSON。parseObject()也是一种原型模式。
原型模式的通用写法
先创建原型IPrototype接口,如下图:
具体实现类,如下图
实际开发中,JDK已经帮我们实现了一个现成的API,我们只需要实现Cloneable接口即可。如下图:
这里增加两个概念:
浅克隆:
浅克隆就是把原对象m1的内存完全copy一份,在堆中开辟一个新的空间放置,里面的引用对象也只是复制了它的classpath,并不会对m1中的所有引用对象再重新开辟一个空间,这样就导致了这两个对象除了基本类型以外,其余类型的成员变量还是指向了同一块内存地址,那么当这个地址被改变的时候,m1,m2中的对应成员变量也会跟着改变(引用关系如下图):
深克隆:
深克隆刚好就是为了解决这个问题,它会把m1中的引用类型等的成员变量也copy一份出来,放到一个新的地址中,然后m2这些成员变量的classpath指向这个新copy出来的地址,这样被copy出来的对象也就完全独立开来了(引用关系如下图):
深克隆和浅克隆的区别:深克隆copy的是值,浅克隆是引用;
克隆会破坏单例模式
如果我们克隆的目标对象是单例对象,那意味着,深克隆就会破坏单例。实际上防止克隆破坏单例解决思路非常简单,禁止深克隆便可。