说在前头:本人为大二在读学生,书写文章的目的是为了对自己掌握的知识和技术进行一定的记录,同时乐于与大家一起分享,因本人资历尚浅,能力有限,文章难免存在一些错漏之处,还请阅读此文章的大牛们见谅与斧正。若在阅读时有任何的问题,也可通过评论提出,本人将根据自身能力对问题进行一定的解答。

前言

原型模式是一种对象创建型模式,用原型模式可以用原型实例指定创建对象的种类,它允许通过一个原型对象创建多个同类型的其他对象,而无需知道该对象的创建细节,在Java中可以直接使用Object提供的clone()方法来实现对象的克隆(浅克隆),或使用序列化的方式完成对象的克隆(深克隆)。

浅克隆

浅克隆主要用于对象的复制,要实现浅克隆的类需要具备以下两个条件:

  • 实现Cloneable接口。在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。

  • 重写Object类中的clone方法。Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,Prototype类需要将clone方法的作用域修改为public类型。

下面是浅克隆具体的代码实现

package com.bosen.prototype;
​
/*** <p>浅克隆</p>* @author Bosen 2021/5/25 2:03*/
public class ShallowPrototype implements Cloneable {
​public String param = new String("测试参数");
​/** 重写clone方法*/@Overridepublic ShallowPrototype clone() {ShallowPrototype prototype = null;try {prototype = (ShallowPrototype) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return prototype;}
}
​

测试类

package com.bosen.prototype;
​
import java.io.IOException;
​
/*** <p>测试类</p>* @author Bosen 2021/5/25 2:14*/
public class Test {public static void main(String[] args) throws IOException, ClassNotFoundException {ShallowPrototype prototype = new ShallowPrototype();ShallowPrototype clone = prototype.clone();System.out.println(clone.param == prototype.param);}
}
​

运行测试类,输出信息如下

可以得知,原型类与克隆类两者对应的成员变量的内存地址是一样的,也就是说浅克隆时,并未对原型类中的成员变量进行克隆,具体原因是因为原型模式使用浅克隆时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并不会去复制;如果要达到引用对象的克隆我们又该如何去实现呢?我们接下来看看深克隆!

深克隆

深克隆与浅克隆的区别:浅克隆是继承Cloneable接口后重写clone方法完成的克隆,而深克隆需要继承序列化接口Serializable,使类可以序列化,然后将类写入流中再从流中取出完成克隆。

深克隆具体代码:

package com.bosen.prototype;
​
import java.io.*;
​
/*** <p>深克隆</p>* @author Bosen 2021/5/25 2:18*/
public class DeepPrototype implements Serializable {
​public String param = new String("测试参数");
​public Object deepClone() throws IOException, ClassNotFoundException {// 将对象写入流中ByteArrayOutputStream bao = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bao);oos.writeObject(this);
​// 将对象从流中取出ByteArrayInputStream bai = new ByteArrayInputStream(bao.toByteArray());ObjectInputStream ois = new ObjectInputStream(bai);return ois.readObject();}
}
​

测试类:

package com.bosen.prototype;
​
import java.io.IOException;
​
/*** <p>测试类</p>* @author Bosen 2021/5/25 2:14*/
public class Test {public static void main(String[] args) throws IOException, ClassNotFoundException {DeepPrototype prototype = new DeepPrototype();DeepPrototype clone = (DeepPrototype) prototype.deepClone();System.out.println(clone.param == prototype.param);}
}
​

启动测试类,输出信息如下:

可以看到,此时原型类的成员变量与克隆类的成员变量内存地址不一致了,也就是说他们的这个成员变量不属于同一个对象,成员变量已经完成了克隆。


总结

原型模式的作用:简化了创建对象的过程,通过一个已有的实例进行复制提高了创建实例的效率,具有较好的可扩展性。

浅克隆和深克隆的区别:使用浅克隆时,当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制;而使用深克隆时,除了对象本身被复制外,对象所包含的所有成员变量也将被复制。

原型模式的使用场景:适合于当一个类初始化需要消耗很多资源时,有很多相似对象时,可以设计一个原型,通过对成员变量的些微修改来实现;需要时可以用深克隆的方式保存对象的状态,比如实现撤销操作等。

 

《23种设计模式之原型模式(2种实现)》相关推荐

  1. ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  2. ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  3. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  4. 信息学奥赛之初赛 第1轮 讲解(01-08课)

    信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...

  5. 信息学奥赛一本通习题答案(五)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  6. 信息学奥赛一本通习题答案(三)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  8. 信息学奥赛一本通题目代码(非题库)

    为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...

  9. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  10. 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离

    首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...

最新文章

  1. 【超赞】技术架构的战略和战术原则
  2. 图论 ---- F. Graph Traveler 记忆化搜索 + 思维预处理(数论同余恒等式)
  3. Go 语言编程 — 数据类型转换
  4. 华为平板wps语音朗读_华为隐藏的这五大功能,个个都很实用,如果你不知道,钱就白花了...
  5. 前后台页面跳转方式搜集
  6. ref和out区别总结
  7. 一个简单的MVC模式练习
  8. java流上传文档把磁盘撑满_BOOT目录磁盘占用满处理
  9. MongoDB学习3——mongoDB的一些基本使用
  10. 嫌贫爱富,是人性,也是典型的消费心理
  11. [COGS 2479] [HZOI 2016] 偏序
  12. python中字节(bytes)是如何转换成整型(long)的?
  13. Go:实现Abs绝对值函数 (附完整源码)
  14. Python银行风控模型的建立(解决Grapviz的中文显示问题)
  15. web前端之幻灯片(二)--自动播放
  16. Command “python setup.py egg_info“ failed with error code 1 in /tmp/pip-buil
  17. X5腾讯内核 安装线上内核本来能用,突然报115错误问题记录
  18. docker安装redis及验证
  19. 带你认识什么是一级指针、二级指针、三级指针
  20. linux debian硬盘安装,硬盘安装Debian

热门文章

  1. Oracle DBlink创建访问远程数据库
  2. 【9505】部落卫队
  3. 将RTSP流保存为本地TS文件
  4. 从零开始实现放置游戏(一)——游戏设计
  5. 关于协方差,协方差矩阵的个人理解
  6. 计算机应用基础0006 19春在线作业1,川大《计算机应用基础0006》20春在线作业1 -0001...
  7. c语言国际编码标准统一编码,88、国际C语言混乱代码大赛-2020.03.11
  8. 阵列分组,不足数,补足
  9. BT1004低电压升压IC
  10. 以太网数据包速率计算方法