在本节中,我们将学习和使用原型模式;这一节学习的原型模式也是创建型 模式的其中之一。再次复习一下:创建型 模式就是描述如何去更好的创建一个对象。

我们都知道,在JAVA 语言中。使用new 关键字创建一个新对象。将新的对象放到堆内存 里面。当然,这个内存肯定是有大小限制的,况且,JAVA 不同于C语言等。 有内存管理机制,就是我们常说的垃圾回收器GC,才可以保证内存不被溢出。

说这些其实就是为了表示:为啥要用单例模式,能节省内存的时候,能用一个对象解决重复的事情,绝对不会创建多个。

概述

原型模式描述的如何快速创建重复的对象,并且减少new 关键字的使用。

  • 抽象原型类
  • 具体原型类
  • 访问类

容我来一个一个解释:

抽象原型类 也就是我们具体要实现的某个类,这个类在JAVA 里面是有具体的接口的,其实是一个空接口,Cloneable

  1. * @author unascribed
  2. * @see java.lang.CloneNotSupportedException
  3. * @see java.lang.Object#clone()
  4. * @since JDK1.0
  5. */
  6. public interface Cloneable {
  7. }

我们会发现,这个类没有任何的方法,怎么来实现它,不要慌。先接着走。

具体原型类 也就是我们具体要克隆 的对象。比如我们重复的要创建100个学生Student 对象,那么具体的学生对象就是具体原型类

  1. public class Student implements Cloneable {
  2. private int id;
  3. private String name;
  4. private int sex;
  5. }

访问类 我就不必多说了

浅克隆和深克隆

原型模式其实也分浅克隆和深克隆。如何理解这两个概念呢?

浅克隆

  1. protected native Object clone() throws CloneNotSupportedException;

浅克隆,只需要具体原型类 实现Cloneable 接口,并且重写父类Object类的clone() 方法,即可实现对象的浅克隆。

  1. Student student1 = new Student(1, "李四");
  2. Student student2 = student1.clone();
  3. System.out.println(student1);
  4. System.out.println(student2);
  5. System.out.println(student1 == student2);
  6. ---------------------
  7. 学号:1,姓名:李四
  8. 学号:1,姓名:李四
  9. false
  • 通过执行clone() 方法即可创建一个相同的,具有同样属性的对象。
  • 并且是新的对象,内存地址有所不同。

我们来看看,对于引用类型的变量,浅克隆是否可以进行克隆;

  1. Teacher teacher = new Teacher(1, "张老师");
  2. Student student1 = new Student(1, "李四", teacher);
  3. Student student2 = student1.clone();
  4. System.out.println(student1);
  5. System.out.println(student2);
  6. System.out.println(student1 == student2);
  7. ------------
  8. 学号:1,姓名:李四,老师=Teacher@1b6d3586
  9. 学号:1,姓名:李四,老师=Teacher@1b6d3586
  10. false

我们发现,引用类型并没有被克隆,也就是说:

特点

  • 浅克隆对于基本类型,可以进行完全的克隆,并且克隆的对象是一个新的对象
  • 但是对象里面的引用,是无法被克隆的。

深克隆(序列化)

何谓序列化?

我们创建的都是保存在内存里面的,只要被虚拟机GC进行回收,那么这个对象的任何属性都是消失,我们能不能找一个方法,将内存中这种对象的属性以及对象的状态通过某种东西保存下来,比如保存到数据库,下次从数据库将这个对象还原到内存里面。 这就是序列化。

  • 序列化 内存对象->序列字符
  • 反序列化 序列字符->内存对象

请参考: https://baike.baidu.com/item/序列化/2890184

JAVA 序列化

  1. * @see java.io.Externalizable
  2. * @since JDK1.1
  3. */
  4. public interface Serializable {
  5. }

JAVA 提供了一个空接口,其实这个接口和上面的Cloneable 一样,都是一个空接口,其实这个空接口就是作为一种标识 你的对象实现了这个接口,JAVA 认为你的这个就可以被序列化 ,就是这么简单。

  1. Teacher teacher = new Teacher(1, "张老师");
  2. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  3. ObjectOutputStream stream = new ObjectOutputStream(outputStream);
  4. stream.writeObject(teacher);
  5. System.out.println(Arrays.toString(outputStream.toByteArray()));
  6. ----------
  7. [-84, -19, 0, 5, 115, 114, 0, 7, 84, 101, 97,。。。。。。

通过将对象序列化、其实也就是将内存中的对象转化为二进制 字节数组

反序列化

  1. Teacher teacher = new Teacher(1, "张老师");
  2. System.out.println(teacher);
  3. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  4. ObjectOutputStream stream = new ObjectOutputStream(outputStream);
  5. stream.writeObject(teacher);
  6. System.out.println(Arrays.toString(outputStream.toByteArray()));
  7. ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(outputStream.toByteArray());
  8. ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
  9. Teacher teacher1 = (Teacher) inputStream.readObject();
  10. System.out.println(teacher1);
  11. ---------------
  12. id=1,name=张老师
  13. [-84, -19, 0, 5, 115, xxxxx,-127, -27, -72, -120]
  14. id=1,name=张老师

通过序列化和反序列化,即可对象的深克隆

小结

这一节,在讲述 原型模式的同时,将原有实现原型模式的clone() 浅克隆,延伸到深克隆这一概念。其实JAVA 的原型模式,实现起来较为简单。但还是要按需要实现,Object 类提供的 clone 浅克隆 是没办法克隆对象的引用类型的。需要克隆引用类型,还是需要序列化 深克隆

参考

http://c.biancheng.net/view/1343.html

https://www.liaoxuefeng.com/wiki/1252599548343744/1298366845681698

代码示例

https://gitee.com/mrc1999/Dev-Examples

欢迎关注

JAVA设计模式 2【创建型】原型模式的理解与使用的更多相关文章

  1. Java设计模式(4)原型模式(Prototype模式)

    Prototype模式定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是: ...

  2. 【java】java设计模式(5):原型模式(Prototype)

    原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制.克隆,产生一个和原对象类似的新对象.本小结会通过对象的复制,进行讲解.在Java中 ...

  3. Java设计模式之创建型模式

    创建型模式分为五类:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式 一.工厂方法模式:接口-实现类.工厂类

  4. 【设计模式】Java设计模式精讲之原型模式

    简单记录 - 慕课网 Java设计模式精讲 Debug方式+内存分析 & 设计模式之禅-秦小波 文章目录 1.原型模式的定义 原型-定义 原型-类型 2.原型模式的实现 原型模式的通用类图 原 ...

  5. Java设计模式_创建型模式_单例模式

    单例模式的实现: 定义一个类,在类中定义该类的静态变量,再定一个一个获取该类的静态变量的方法. UML图:

  6. Java设计模式(22)命令模式(Command模式)

    Command模式是最让我疑惑的一个模式,我在阅读了很多代码后,才感觉隐约掌握其大概原理,我认为理解设计模式最主要是掌握起原理构造,这样才对自己实际编程有指导作用.Command模式实际上不是个很具体 ...

  7. Java设计模式(19)状态模式(State模式)

    State的定义:不同的状态,不同的行为:或者说,每个状态有着相应的行为. 何时使用状态模式 State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If else ...

  8. Java设计模式(18)策略模式(Strategy模式)

    Strategy是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类. Stratrgy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一个是线条曲线, ...

  9. Java设计模式(15)备忘录模式(Memento模式)

    Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public class ...

  10. Java设计模式(12)迭代模式(Iterator模式)

    上了这么多年学,我发现一个问题,好象老师都很喜欢点名,甚至点名都成了某些老师的嗜好,一日不点名,就饭吃不香,觉睡不好似的,我就觉得很奇怪,你的课要是讲的好,同学又怎么会不来听课呢,殊不知:“误人子弟, ...

随机推荐

  1. Python 每日一练(3)

    引言 今天的每日一练,学习了一下用Python生成四位的图像验证码,就是我们常常在登录时见到的那种(#`O′) 思路分析 正如常见的那种图像验证码,它是由数字和字母的随机组合产生的,所以我们首先的第一 ...

  2. volatile关键字与内存可见性&原子变量与CAS算法

    1 .volatile 关键字:当多个线程进行操作共享数据时, 可以保证内存中的数据可见 2 .原子变量:jdk1.5后java.util.concurrent.atomic 包下提供常用的原子变量 ...

  3. django-模型层(ORM语法)

    今日内容概要(重要) 模型层(ORM语法):跟数据库打交道的 单表查询(增删改查) 常见的十几种查询方法 神奇的双下划线查询 多表操作 外键字段的增删改查 跨表查询(重点) 子查询 联表查询 今日内容 ...

  4. RabbitMQ 高级应用

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 本文RabbitMQ版本为rabbitmq-server-3.7.17,erlang为erlang-22.0.7.请各位去官网查看版本匹配和下载 ...

  5. seo网站优化收录过少的病因分析-智狐seo顾问

    seo网站优化收录过少的病因分析 很多网站优化人员都了解,一个网站收录的重要性,企业网站要想可以在百度中占据一个良好的排名,获取的权重更高,那么网站收录自然就上去了,很多站长们在操作的过程中就会出现不 ...

  6. Java实现 LeetCode 812 最大三角形面积 (暴力)

    812. 最大三角形面积 给定包含多个点的集合,从其中取三个点组成三角形,返回能组成的最大三角形的面积. 示例: 输入: points = [[0,0],[0,1],[1,0],[0,2],[2,0] ...

  7. Java实现 LeetCode 436 寻找右区间

    436. 寻找右区间 给定一组区间,对于每一个区间 i,检查是否存在一个区间 j,它的起始点大于或等于区间 i 的终点,这可以称为 j 在 i 的"右侧". 对于任何区间,你需要存 ...

  8. Java实现 LeetCode 79 单词搜索

    79. 单词搜索 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格. ...

  9. Java实现 LeetCode 42 接雨水

    42. 接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这 ...

  10. IDEA,PyCharm系列软件常用快捷键

    首先介绍一下小编常用的快捷键: 注释 ctrl+/ 当想看某个类或者某个方法的时候 ctrl+鼠标左键单击 运行程序 ctrl+shift+f10 调试程序 ctrl+shift+f9 撤销 ctrl ...