1、例如
创建十只羊,后面九只羊都和第一只羊一致
传统的方式
Sheep sheep = new Sheep("tom",1,"red");
Sheep sheep2 = new Sheep(sheep.getName,sheep.getAge,sheep.getColor);
Sheep sheep3 = new Sheep(sheep.getName,sheep.getAge,sheep.getColor);
..
- 传统方式的优点:比较好理解,简单易操作
- 在创建新的对象时,总是需要重新获取原始对象的属性,如果创建的对象比较复杂时,效率较低。
- 总是需要重新初始化对象,而不是动态的获取的对象运行时状态,不够灵活。
改进的方式思路:
java中Object类时所有类的基类,Object
类提供了一个clone()
方法,该方法可以将一个java对象复制一份,但是需要实现clone的java类必须要实现一个接口Cloneable(可克隆的),该接口表示该类能够复制且具有复制的能力 => 原型模式
2、原型模式基本介绍
- 原型模式(Propotype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象
- 原型模式是一种创建设计模式,允许在一个对象再创建另外一个可定制的对象,无需知道如果创建的细节
- 工作原理是:通过一个原型对象传给哪个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝他们自己来实施建,既
对象.clone()
- 形象的理解:孙大圣拔出猴毛,变出其他孙大圣
2.1 UML类图
prototype: 原型类,声明一个克隆自己的接口
ContretePrototype: 具体的原型类,实现一个克隆自己的操作
Client : 客户端,让一个原型对象 克隆自己从而创建一个新的对象,属性一致
3、原型模式代码实现思路
创建10只羊,要求后9只羊的属性和第一只羊一样(克隆9只)
- 创建一个Sheep类,重写Object的clone()方法,实现Cloneable接口
**
- 在客户端类,直接创建出第一个sheep,然后调用他的clone方法就能克隆了
4、原型模式在Spring框架中的使用
spring中原型bean的创建,就是原型模式的应用<bean id="student" class="com.yixuexi.test.Student" scope="prototype"/>
可以通过scope来配置,是否是单例还是原型
- prototype 是原型,多例,会克隆多个对象
- singleton 是单例,只会创建一个对象
5、原型模式的注意事项和细节
- 创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率。
- 不用重新初始化对象,而是动态的获取对象运行时的状态。
**
- 如果原始对象发生变化(增加或者减少属性),其他克隆对象的也会发生相应的变化,无需需改代码
- 在实现深克隆的时候可能需要比较复杂的代码(需要给每个类都配置一个clone方法)
- 缺点:需要为每一个类配备一个克隆方法,这对全新的类来说不是很难,但是对已有的类进行改造时,需要修改其源码,违背了OCP原则
6、深拷贝和浅拷贝
6.1 浅拷贝
- 浅拷贝指的是:java只拷贝你指定的对象,至于你指定的对象里面的别的对象,它不拷贝,还是把引用给你,共享变量,这是一种非常不安全的方式,需要特别注意。
- 可以通过查看指定拷贝对象中的其他对象的 hashCode来判断是浅拷贝,因为都是一个引用,所以哈希值一致
- 对于数据类型是基本数据类型得成员变量(包括String),浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。
浅拷贝使用的就是默认的clone()方法来实现(直接IDEA中重写clone()方法就是浅克隆)
复制对象的所有基本数据类型的成员变量值
- 为所有引用数据类的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,知道该对象的可达到所有对象,也就是说,每个对象进行深拷贝 都要对整个对象中的引用对象进行拷贝
- 深拷贝的实现方式1:重写clone方法来实现深拷贝(在AAA的clone方法里把BBB实例化出来了:)—->
- 深拷贝的实现方式2:通过序列化实现深拷贝(推荐使用)