创建型模式-原型模式

文章目录

  • 一、原型模式
    • 1. 概述
    • 2. 结构
    • 3. 实现
    • 4. 案例
    • 1.5 使用场景
    • 1.6 扩展(深克隆)

一、原型模式

1. 概述

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。

2. 结构

原型模式包含如下角色:

  • 抽象原型类:规定了具体原型对象必须实现的 clone() 方法。
  • 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
  • 访问类:使用具体原型类中的 clone() 方法来复制新的对象。

接口类图如下:

在这里插入图片描述

3. 实现

原型模式的克隆分为浅克隆和深克隆。

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

Java中的Object类中提供了 clone() 方法来实现浅克隆。 Cloneable 接口是上面的类图中的抽象原型类,而实现了Cloneable接口的子实现类就是具体的原型类。

Realizetype(具体的原型类):

public class Realizetype implements Cloneable {public Realizetype() {System.out.println("具体的原型对象创建完成!");}@Overridepublic Realizetype clone() throws CloneNotSupportedException {System.out.println("具体原型复制成功!");return (Realizetype) super.clone();}
}

PrototypeTest(测试访问类):

public class PrototypeTest {public static void main(String[] args) throws CloneNotSupportedException {//创建一个原型类对象Realizetype realizetype = new Realizetype();//调用Realizetype类中的clone方法进行对象的克隆Realizetype clone = realizetype.clone();System.out.println("原型对象和克隆出来的是否是同一个对象?" + (realizetype == clone));}
}

运行结果为:
在这里插入图片描述

4. 案例

用原型模式生成“三好学生”奖状

同一学校的“三好学生”奖状除了获奖人姓名不同,其他都相同,可以使用原型模式复制多个“三好学生”奖状出来,然后在修改奖状上的名字即可。

在这里插入图片描述

奖状类:

public class Citation implements Cloneable {private String name;public void setName(String name) {this.name = name;}public String getName() {return (this.name);}public void show() {System.out.println(name + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!");}@Overridepublic Citation clone() throws CloneNotSupportedException {return (Citation) super.clone();}
}

测试访问类:

public class CitationTest {public static void main(String[] args) throws CloneNotSupportedException {Citation c1 = new Citation();c1.setName("张三");//复制奖状Citation c2 = c1.clone();//将奖状的名字修改李四c2.setName("李四");c1.show();c2.show();}
}

运行结果为:
在这里插入图片描述

1.5 使用场景

  • 对象的创建非常复杂,可以使用原型模式快捷的创建对象。
  • 性能和安全要求比较高。

1.6 扩展(深克隆)

将上面的“三好学生”奖状的案例中Citation类的name属性修改为Student类型的属性。

奖状类:

public class Citation implements Cloneable {private Student stu;public Student getStu() {return stu;}public void setStu(Student stu) {this.stu = stu;}void show() {System.out.println(stu.getName() + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!");}@Overridepublic Citation clone() throws CloneNotSupportedException {return (Citation) super.clone();}
}

学生类:

public class Student {private String name;private String address;public Student(String name, String address) {this.name = name;this.address = address;}public Student() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}

测试类:

public class CitationTest {public static void main(String[] args) throws CloneNotSupportedException {Citation c1 = new Citation();Student stu = new Student("张三", "西安");c1.setStu(stu);//复制奖状Citation c2 = c1.clone();//获取c2奖状所属学生对象Student stu1 = c2.getStu();stu1.setName("李四");//判断stu对象和stu1对象是否是同一个对象System.out.println("stu和stu1是同一个对象?" + (stu == stu1));c1.show();c2.show();}
}

运行结果为:
在这里插入图片描述

说明:
​ stu对象和stu1对象是同一个对象,就会产生将stu1对象中name属性值改为“李四”,两个Citation(奖状)对象中显示的都是李四。这就是浅克隆的效果,对具体原型类(Citation)中的引用类型的属性进行引用的复制。这种情况需要使用深克隆,而进行深克隆需要使用对象流。

public class CitationTest1 {public static void main(String[] args) throws Exception {Citation c1 = new Citation();Student stu = new Student("张三", "西安");c1.setStu(stu);//创建对象输出流对象ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Think\\Desktop\\b.txt"));//将c1对象写出到文件中oos.writeObject(c1);oos.close();//创建对象出入流对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\Think\\Desktop\\b.txt"));//读取对象Citation c2 = (Citation) ois.readObject();//获取c2奖状所属学生对象Student stu1 = c2.getStu();stu1.setName("李四");//判断stu对象和stu1对象是否是同一个对象System.out.println("stu和stu1是同一个对象?" + (stu == stu1));c1.show();c2.show();}
}

运行结果为:
在这里插入图片描述
注意:Citation类和Student类必须实现Serializable接口,否则会抛NotSerializableException异常。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/36498.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用windows搭建WebDAV服务,并内网穿透公网访问【无公网IP】

文章目录 1. 安装IIS必要WebDav组件2. 客户端测试3. 使用cpolar内网穿透,将WebDav服务暴露在公网3.1 打开Web-UI管理界面3.2 创建隧道3.3 查看在线隧道列表3.4 浏览器访问测试 4. 安装Raidrive客户端4.1 连接WebDav服务器4.2 连接成功4.2 连接成功 1. Linux(centos8…

【Vue-Router】路由入门

路由(Routing)是指确定网站或应用程序中特定页面的方式。在Web开发中,路由用于根据URL的不同部分来确定应用程序中应该显示哪个内容。 构建前端项目 npm init vuelatest //或者 npm init vitelatest安装依赖和路由 npm install npm instal…

ATF BL1 UFS初始化简单分析

ATF BL1 UFS初始化分析 1 ATF的下载链接2 ATF BL1 UFS 初始化简易流程图3 ATF BL1 ufs初始化简单过程分析3.1 调用过程3.2 hikey960_ufs_init3.3 dw_ufs_init3.3 ufs_init 以海思hikey960为例来介绍,简单介绍在ATF BL1阶段的初始化处理。 1 ATF的下载链接 https:/…

蓝帽杯 取证2022

网站取证 网站取证_1 下载附件 并解压 得到了一个文件以及一个压缩包 解压压缩包 用火绒查病毒 发现后门 打开文件路径之后 发现了一句话木马 解出flag 网站取证_2 让找数据库链接的明文密码 打开www文件找找 查看数据库配置文件/application/database.php(CodeI…

截止到目前全量主体总数有多少?

企业主体类型 企业主体类型有很多种,一般我们会分为公司(有限责任)、合伙企业、个人独资企业、个体经营户这些类别。 今天我们按照企业,个体,组织的分类方式来看各个主体的总数。 企业:统一社会信用代码…

ARTS 挑战打卡的第7天 --- Ubuntu中的WindTerm如何设置成中文,并且关闭shell中Tab键声音(Tips)

前言 (1)Windterm是一个非常优秀的终端神器。关于他的下载我就不多说了,网上很多。今天我就分享一个国内目前没有找到的这方面的资料——Ubuntu中的WindTerm如何设置成中文,并且关闭shell中Tab键声音。 将WindTerm设置成中文 &…

Unity zSpace 开发

文章目录 1.下载 zSpace 开发环境1.1 zCore Unity Package1.2 zView Unity Package 2. 导入工程3. 发布设置4.功能实现4.1 用触控笔来实现对模型的拖拽: 5. 后续更新 1.下载 zSpace 开发环境 官网地址 1.1 zCore Unity Package zSpace 开发核心必须 1.2 zView …

机器人CPP编程基础-05完结The End

非常不可思议……之前四篇博文竟然有超过100的阅读量…… 此文此部分终结,没有继续写下去的必要了。 插入一个分享: 编程基础不重要了,只要明确需求,借助AI工具就能完成一个项目。 当然也不是一次成功,工具使用也需要…

计算机视觉一 —— 介绍与环境安装

傲不可长 欲不可纵 乐不可极 志不可满 一、介绍 研究理论和应用 - 研究如何使机器“看”的科学 - 让计算机具有人类视觉的所有功能 - 让计算机从图像中,提取有用的信息,并解释 - 重构人眼;重构视觉皮层;重构大脑剩余部分 计…

利用ChatGPT绘制思维导图——以新能源汽车竞品分析报告为例

随着人们对环境保护的日益关注和传统燃油汽车的限制,全球范围内对新能源汽车的需求不断增长。新能源汽车市场的激烈竞争使得了解各个竞品的特点和优劣成为关键。然而,针对这一领域的详尽竞品分析却常常需要大量时间和精力。 在此背景下,人工智…

Qt+C++自定义控件仪表盘动画仿真

程序示例精选 QtC自定义控件仪表盘动画仿真 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<QtC自定义控件仪表盘动画仿真>>编写代码&#xff0c;代码整洁&#xff0c;规则&…

2023国赛数学建模D题思路分析

文章目录 0 赛题思路1 竞赛信息2 竞赛时间3 建模常见问题类型3.1 分类问题3.2 优化问题3.3 预测问题3.4 评价问题 4 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 竞赛信息 全国大学生数学建模…

PHP原生类

什么是php原生类 原生类就是php内置类&#xff0c;不用定义php自带的类&#xff0c;即不需要在当前脚本写出&#xff0c;但也可以实例化的类 我们可以通过脚本找一下php原生类 <?php $classes get_declared_classes(); foreach ($classes as $class) {$methods get_clas…

Docker的基本概念及镜像加速器的配置

1.Docker的概念 由于代码运行环境不同&#xff0c;代码运行会出现水土不服的情况。运用docker容器会把环境进行打包&#xff0c;避免水土不服。docker是一种容器技术&#xff0c;它解决软件跨环境迁移的问题。 2&#xff0c;安装Docker 3.Docker架构 4.Docker镜像加速器的配…

我们常说这个pycharm里有陷阱,第三方库导入失败,看这里!

最近有小伙伴遇到了明明安装了 python 第三方库&#xff0c;但是在 pycharm 当中却导入不成功的问题。 ​ 一直以来&#xff0c;也有不少初学 python 的小伙伴&#xff0c;一不小心就跳进了虚拟环境和系统环境的【陷阱】中。 本文就基于此问题&#xff0c;来说说在 pycharm 当…

Spring Cloud 面试突击2

Spring Cloud 面试突击2 高并发&#xff1a;是一种系统运行过程中遇到的短时间大量的请求操作 响应时间&#xff1a; 吞吐量&#xff1a; QPS&#xff1a;数据库为维度 TPS 并发用户数 并发的维度&#xff1a;很多的 并发是不是达到的当前系统的瓶颈 缓存 &#xff08…

计算机网络—IP

这里写目录标题 IP的基本认识网络层与数据链路层有什么关系IP地址基础知识IP 地址的分类什么是A、B、C类地址广播地址用来做什么什么是D、E类广播多播地址用于什么IP分类的优点IP分类的缺点 无分类地址CIDR如何划分网络号和主机号怎么进性子网划分 公有 IP 地址与私有 IP 地址公…

指针---进阶篇(二)

指针---进阶篇&#xff08;二&#xff09; 前言一、函数指针1.抛砖引玉2.如何判断函数指针&#xff1f;&#xff08;方法总结&#xff09; 二、函数指针数组1.什么是函数指针数组&#xff1f;2.讲解函数指针数组3.模拟计算器&#xff1a;讲解函数指针数组 三、指向函数指针数组…

Maven基础之仓库、命令、插件机制

文章目录 Maven 仓库中央仓库和本地仓库中央仓库本地仓库 Maven 命令generate 命令compile 命令clean 命令test 命令package 命令install 命令 Maven 插件机制官方插件&#xff1a;Compile 插件Tomcat 7 插件 Maven 仓库 中央仓库和本地仓库 [✎] 简单一点说 中央仓库是一个网…

Redis复制

在Redis中&#xff0c;用户可以通过执行SLAVEOF命令或者设置slaveof选项&#xff0c;让一个服务器去复制(replicate) 另一个服务器&#xff0c;我们称呼被复制的服务器为主服务器(master)&#xff0c;而对主服务器进行复制的服务器则被称为从服务器(slave)&#xff0c;如下图所…