前言
创建型模式的有一个模式:原型模式
Java中实现原型模式需要理解复制
JavaSE笔记(2.7)Java基础 - 复制
目录
原型模式
需求
在有些系统中,存在大量相同或相似对象的创建问题,如果用传统的构造函数来创建对象,会比较复杂且耗时耗资源,用原型模式生成对象就很高效
原型模式通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象
定义
原型模式(Prototype Pattern):原型模式是一种对象创建型模式,用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。原型模式允许一个对象再创建另外一个可定制的对象,无须知道任何创建的细节
结构
包含3个角色:
- 抽象原型类(Prototype):规定了具体原型对象必须实现的接口
- 具体原型类(ConcretePrototype):实现抽象原型类的 clone() 方法,它是可被复制的对象
- 客户类(Client):使用具体原型类中的 clone() 方法来复制新的对象
具体实现
package com.company.DesignPatterns;
class Prototype implements Cloneable{
Prototype(){
System.out.println("初始对象创建");
}
//返回克隆对象
public Object clone() throws CloneNotSupportedException {
System.out.println("克隆对象");
return super.clone();
}
}
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
Prototype prototype=new Prototype();
//克隆对象
Prototype prototypeClone= (Prototype) prototype.clone();
System.out.print("两个对象是否相同:"+(prototype==prototypeClone));
}
}
扫描二维码关注公众号,回复:
9918951 查看本文章
深克隆、浅克隆
浅克隆复制对象,但对于对象中的成员变量的引用仅复制引用
深克隆不仅复制对象,还就对象中的引用对象也一起复制
什么意思?
public class Person implements Cloneable {
private int id;
private String name;
private Subject subject;
如果一个类的成员对象是另一个对象的引用(例Person的成员变量Subject)
浅克隆仅复制Person类,Person类的成员变量Subject仅复制引用,所以如果原对象的Subject改变,克隆对象的Subject也会改变
而深克隆两者都会复制
原型模式的优缺点
优点:
- 当创建新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程,通过一个已有实例可以提高新实例的创建效率。
- 可以动态增加或减少产品类。
- 原型模式提供了简化的创建结构。
- 可以使用深克隆的方式保存对象的状态
缺点:
- 需要为每一个类配备一个克隆方法,而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。
- 在实现深克隆时需要编写较为复杂的代码
原型模式应用场景
适用环境:
- 创建新对象成本较大,新的对象可以通过原型模式对已有对象进行复制来获得,如果是相似对象,则可以对其属性稍作修改。
- 如果系统要保存对象的状态,而对象的状态变化很小,或者对象本身占内存不大的时候,也可以使用原型模式配合备忘录模式来应用。相反,如果对象的状态变化很大,或者对象占用的内存很大,那么采用状态模式会比原型模式更好。
- 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便
一些应用:
- 复制(Ctrl + C)和粘贴(Ctrl + V)操作就是原型模式的应用,复制得到的对象与原型对象是两个类型相同但内存地址不同的对象
- Spring中,用户也可以采用原型模式来创建新的bean实例,从而实现每次获取的是通过克隆生成的新实例,对其进行修改时对原有实例对象不造成任何影响
模式扩展
- 带原型管理器的原型模式
在原型模式的基础上增加了一个原型管理器 PrototypeManager 类,该类用 HashMap 保存多个复制的原型,Client 类可以通过管理器的 get(String id) 方法从中获取复制的原型
- 相似对象的复制
通过原型模式获得相同对象后可以再对其属性进行修改,从而获取所需对象,如多个学生对象的信息的区别在于性别、姓名和年龄,而专业、学院、学校等信息都相同,为了简化创建过程,可以通过原型模式来实现相似对象的复制
总结
- 原型模式作用在于复制对象,减少了创建对象的消耗
- 原型模式有三个成员:抽象原型类是定义具有克隆自己的方法的接口;具体原型类实现具体的克隆方法,在克隆方法中返回自己的一个克隆对象;让一个原型克隆自身从而创建一个新的对象,在客户类中只需要直接实例化或通过工厂方法等方式创建一个对象,再通过调用该对象的克隆方法复制得到多个相同的对象
- Java中克隆对象:深克隆、浅克隆;浅克隆复制对象,仅对对象成员引用;深克隆两者都复制
- 原型模式最大的优点:可以快速复制多个对象,简化创建;最大的缺点:每个类需要继承Cloneable接口,实现clone方法
- 原型模式适用于:创建对象开销大;系统需要保存对象的状态,对象变化状态很小
- 扩展:带原型管理器的原型模式;相似对象的复制