现有一只羊叫Dolly,年龄7岁,颜色为白色,请编写程序创建和10个和Dolly一模一样的小羊。
传统方法:
优点:易于操作,比较好理解
缺点:
1)在创建新的对象时,总是要手动去给羊赋值拷贝属性,如果对象比较复杂,则效率低下。
2)总是要重新初始化对象,而不是动态的获取对象的运行时状态。不够灵活。
改进思路:Object提供了clone()方法,拷贝对象属性,该方法可以将java对象复制一份,但前提是对象必须的实现cloneable接口,该接口表示对象用友复制能力。从而引出了原型模式。
基本介绍:
1)原型模式指出:用原型实例指出创建对象的种类,并且通过拷贝这些对象的原型创建出新的对象。
2)原型模式是一种创建型模式,允许一个对象再创建另一个可以定制的对象。
3)工作原理就是将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝他们自己来进行创建。即对象clone()
4)形象的解释:孙悟空拔毛,变出其他孙大圣。
图解说明:
Proptotype:原型类,声明一个克隆自己的接口。
PrototypeV1:具体的原型类,实现一个克隆自己的接口。
PrototypeV2:具体的原型类,实现一个克隆自己的接口。
Client:让一个克隆对象创建自己,从而创建一个新的对象。
1)原型在Spring中原型bean创建,就是原型模式的应用
2)代码分析+Debug源码:
深入讨论深拷贝和浅拷贝
浅拷贝介绍:
1)数据类型为基本类型的成员变量,浅拷贝会直接进行值的传递,也就是说将该属性值复制一份给新的对象。
2)对于数据类型为引用类型的成员变量(比如说数组、对象)浅拷贝会进行引用的传递。也就是说只是将该成员变量的引用值(内存地址)复制一份给新的对象,因此实际上两个对象的成员变量都指向同一个实例。在这种情况下,在一个对象中修改成员变量的属性,会影响到另一个对象。
3)浅拷贝使用
(Sheep)super.clone();
来实现。
深拷贝介绍
1)复制对象的所有基本类型成员变量的值
2)为所有引用类型的成员变量申请存储空间,并复制每个引用类型成员变量所引用的对象。直到该对象可大的所有对象。也就是说对对象进行深拷贝要对整个对象进行拷贝。
3)深拷贝实现方法:①、重写clone方法来实现;②、通过对象序列化来实现深拷贝(推荐)。
原型模式的注意事项和细节:
1)创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程。同时也能够提高效率
2)不同重新初始化对象,而且动态的获得对象的运行时状态。
3)如果原始对象有变化(增加或者减少属性),其他克隆对象也会发生相应的变化,无需修改代码。
4)实现深克隆的时候可能需要比较复杂的代码。
5)缺点:需要为每一个类配置一个克隆方法,对新对象来说不是很难,但对已有对象来说可能需要修改原来代码,未被了ocp原则。这点请注意。