当前位置: 首页 > news >正文

10 创建型模式-原型模式

引言:
创建对象的五种方式:

  1. 通过new关键字
  2. 通过Class类的newInstance()方法
  3. 通过Constructor类的newInstance()方法
  4. 利用Clone方法
  5. 反序列化

Clone方法:
其实现方式正是通过调用 Object 类的 clone() 方法来完成。

protected native Object clone() throws CloneNotSupportedException;
public class Person implements Cloneable{public String pname;public int page;public Address address;public Person() {}public Person(String pname,int page){this.pname = pname;this.page = page;this.address = new Address();}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}public void setAddress(String provices,String city ){address.setAddress(provices, city);}public void display(String name){System.out.println(name+":"+"pname=" + pname + ", page=" + page +","+ address);}public String getPname() {return pname;}public void setPname(String pname) {this.pname = pname;}public int getPage() {return page;}public void setPage(int page) {this.page = page;}}
public class Address {private String provices;private String city;public void setAddress(String provices,String city){this.provices = provices;this.city = city;}@Overridepublic String toString() {return "Address [provices=" + provices + ", city=" + city + "]";}}

这是一个我们要进行赋值的原始类 Person。下面我们产生一个 Person 对象,并调用其 clone 方法复制一个新的对象。
注意:调用对象的 clone 方法,必须要让类实现 Cloneable 接口,并且覆写 clone 方法。
测试:

@Test
public void testShallowClone() throws Exception{Person p1 = new Person("zhangsan",21);p1.setAddress("湖北省", "武汉市");Person p2 = (Person) p1.clone();System.out.println("p1:"+p1);System.out.println("p1.getPname:"+p1.getPname().hashCode());System.out.println("p2:"+p2);System.out.println("p2.getPname:"+p2.getPname().hashCode());p1.display("p1");p2.display("p2");p2.setAddress("湖北省", "荆州市");System.out.println("将复制之后的对象地址修改:");p1.display("p1");p2.display("p2");
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

深拷贝

在这里插入图片描述
在这里插入图片描述

如何实现深拷贝?
  1. 让每个引用类型属性内部都重写clone() 方法
  2. 利用序列化
1 原型模式介绍

定义: 原型模式(Prototype Design Pattern)用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。

西游记中的孙悟空 拔毛变小猴,孙悟空这种根据自己的形状复制出多个身外化身的技巧,在面向对象软件设计领域被称为原型模式.孙悟空就是原型对象.
在这里插入图片描述
在这里插入图片描述

2 原型模式原理

在这里插入图片描述
在这里插入图片描述

3 深克隆与浅克隆

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3) 浅克隆代码实现:

在这里插入图片描述
测试

@Test
public void test01() throws CloneNotSupportedException {ConcretePrototype c1 = new ConcretePrototype();ConcretePrototype c2 = c1.clone();//输出falseSystem.out.println("对象c1和c2是同一个对象?" + (c1==c2));
}
4) 深克隆代码实现
/*** 具体原型类* 实现Cloneable标识接口,表示当前类对象可复制**/
public class ConcretePrototype implements Cloneable, Serializable {private Person person;public Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;}public void show(){System.out.println("嫌疑人姓名: " + person.getName());}public ConcretePrototype() {System.out.println("具体原型对象创建成功!");}@Overrideprotected ConcretePrototype clone() throws CloneNotSupportedException {System.out.println("克隆对象复制成功!");return (ConcretePrototype) super.clone();}
}
import java.io.Serializable;public class Person implements Serializable {private String name;public Person() {}public Person(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
//浅拷贝@Testpublic void test02() throws CloneNotSupportedException {ConcretePrototype c1 = new ConcretePrototype();Person p1 = new Person("峰哥");c1.setPerson(p1);//复制c1ConcretePrototype c2 = c1.clone();Person p2 = c2.getPerson();p2.setName("凡哥");c1.show();c2.show();//输出true,克隆对象和原型对象还是共享name属性的System.out.println("对象p1和对象p2是同一个对象吗?" + (p1 == p2));}

如果有需求场景中不允许共享同一对象,那么就需要使用深拷贝,如果想要进行深拷贝需要使用到对象序列化流 (对象序列化之后,再进行反序列化获取到的是不同对象).
在这里插入图片描述

4 原型模式应用实例

在这里插入图片描述
在这里插入图片描述

代码实现
广告模板代码
/*** 广告模板**/
public class AdvTemplate {//广告信名称private String advSubject = "xx银行本月还款达标,可抽iPhone 13等好礼!";//广告信内容private String advContext = "达标用户请在2022年3月1日到2022年3月30日参与抽奖......";public String getAdvSubject() {return advSubject;}public void setAdvSubject(String advSubject) {this.advSubject = advSubject;}public String getAdvContext() {return advContext;}public void setAdvContext(String advContext) {this.advContext = advContext;}
}

邮件类代码

/*** 邮件类**/
public class Mail {private String receiver; //收件人private String subject; //邮件名称private String appellation; //称呼private String context;  //邮件内容private String tail; //邮件尾部 "xx版权所有"public Mail(AdvTemplate advTemplate) {this.subject = advTemplate.getAdvSubject();this.context = advTemplate.getAdvContext();}public String getReceiver() {return receiver;}public void setReceiver(String receiver) {this.receiver = receiver;}public String getSubject() {return subject;}public void setSubject(String subject) {this.subject = subject;}public String getAppellation() {return appellation;}public void setAppellation(String appellation) {this.appellation = appellation;}public String getContext() {return context;}public void setContext(String context) {this.context = context;}public String getTail() {return tail;}public void setTail(String tail) {this.tail = tail;}
}

客户类

/*** 业务场景**/
public class Client {//发送邮件的数量private static int MAX_COUNT = 6;//发送邮件public static void sendMail(Mail mail){System.out.println("标题: " + mail.getSubject() + "\t 收件人: " + mail.getReceiver()+ "\t ...发送成功!");}public static void main(String[] args) {int i = 0;//定义模板Mail mail = new Mail(new AdvTemplate());mail.setTail("xxx银行版权所有");while(i < MAX_COUNT){//每封邮件不同的信息mail.setAppellation(" 先生 (女士)");Random random = new Random();int num = random.nextInt(999999999);mail.setReceiver(num + "@"+"mashibing.com");//发送邮件sendMail(mail);i++;}}}

在这里插入图片描述
代码重构
Mail类

public class Mail implements Cloneable {private String receiver; //收件人private String subject; //邮件名称private String appellation; //称呼private String context;  //邮件内容private String tail; //邮件尾部 "xx版权所有"public Mail(AdvTemplate advTemplate) {this.subject = advTemplate.getAdvSubject();this.context = advTemplate.getAdvContext();}public String getReceiver() {return receiver;}public void setReceiver(String receiver) {this.receiver = receiver;}public String getSubject() {return subject;}public void setSubject(String subject) {this.subject = subject;}public String getAppellation() {return appellation;}public void setAppellation(String appellation) {this.appellation = appellation;}public String getContext() {return context;}public void setContext(String context) {this.context = context;}public String getTail() {return tail;}public void setTail(String tail) {this.tail = tail;}@Overrideprotected Mail clone() {Mail mail = null;try {return  (Mail)super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}

Client类

public class Client {//发送邮件的数量private static int MAX_COUNT = 6;//发送邮件public static void sendMail(Mail mail){System.out.println("标题: " + mail.getSubject() + "\t 收件人: " + mail.getReceiver()+ "\t ...发送成功!");}public static void main(String[] args) {int i = 0;//定义模板Mail mail = new Mail(new AdvTemplate());mail.setTail("xxx银行版权所有");while(i < MAX_COUNT){//每封邮件不同的信息Mail cloneMail = mail.clone();cloneMail.setAppellation(" 先生 (女士)");Random random = new Random();int num = random.nextInt(999999999);cloneMail.setReceiver(num + "@"+"mashibing.com");//发送邮件sendMail(cloneMail);i++;}}
}
5 原型模式总结

原型模式的优点:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
原型模式缺点:
需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的内部,当对已有的类进行改造时需要修改源代码,违背了开闭原则.

使用场景

在这里插入图片描述

相关文章:

10 创建型模式-原型模式

引言&#xff1a; 创建对象的五种方式&#xff1a; 通过new关键字通过Class类的newInstance()方法通过Constructor类的newInstance()方法利用Clone方法反序列化 Clone方法&#xff1a; 其实现方式正是通过调用 Object 类的 clone() 方法来完成。 protected native Object cl…...

MSQL系列(七) Mysql实战-SQL语句Join,exists,in的区别

Mysql实战-SQL语句Join&#xff0c;exists&#xff0c;in的区别 前面我们讲解了索引的存储结构&#xff0c;BTree的索引结构&#xff0c;以及索引最左侧匹配原则及讲解一下常用的SQL语句的优化建议&#xff0c;今天我们来详细讲解一下 我们经常使用的 join&#xff0c; exist&…...

最新壁纸自动采集系统网站PHP源码/360壁纸官方数据接口采集/ZHEYI采集源码

源码介绍&#xff1a; 最新壁纸自动采集系统网站PHP源码&#xff0c;它是ZHEYI自动采集源码&#xff0c;能够在360壁纸官方数据接口采集。很好用的壁纸网站源码分享&#xff0c;仅供学习&#xff0c;请勿商用。 ZHEYI自动采集壁纸PHP源码&#xff0c;能全自动采集高清壁纸网源…...

Redis在分布式场景下的应用

分布式缓存 缓存的基本作用是在高并发场景下对应服务的保护缓冲 – 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题&#xff1a; redis由于高强度性能采用内存 但是意味着丢失的风险单结点redis并发能力有限分布式服务中数据过多 依赖内存的redis 明显单机不…...

2316. 统计无向图中无法互相到达点对数

2316. 统计无向图中无法互相到达点对数 难度: 中等 来源: 每日一题 2023.10.21 给你一个整数 n &#xff0c;表示一张 无向图 中有 n 个节点&#xff0c;编号为 0 到 n - 1 。同时给你一个二维整数数组 edges &#xff0c;其中 edges[i] [ai, bi] 表示节点 ai 和 bi 之间…...

Selenium定向爬取海量精美图片及搜索引擎杂谈

我自认为这是自己写过博客中一篇比较优秀的文章,同时也是在深夜凌晨2点满怀着激情和愉悦之心完成的。首先通过这篇文章,你能学到以下几点: 1.可以了解Python简单爬取图片的一些思路和方法 2.学习Selenium自动、测试分析动态网页和正则表达式的区别和共同点 …...

面试题—JAVA基础①

文章目录 1.Java面向对象有哪些特征&#xff1f;2.ArrayList和LinkedList有什么区别&#xff1f;3.Java接口和抽象类有哪些区别&#xff1f;4.hashcode和equals如何使用&#xff1f;5.try-catch6.局部变量和实例变量7.String、StringBuffer、StringBuilder 的区别&#xff1f;8…...

naive-ui的n-data-table标签奇特bug记录

具体参考之前的博文&#xff1a;vueday02——使用naive-ui做一个ACM看榜-CSDN博客 具体代码在这里面 原因&#xff1a;在本地运行的时候&#xff0c;datatable里面使用列表渲染成字符串前端设置样式进行转换&#xff0c;但是在正式部署的时候&#xff0c;这个组件没有将其自动…...

微信小程序OA会议系统个人中心授权登入

在我们的完成微信登入授权之前&#xff0c;首先我们要完成我们前面所写的代码&#xff0c;如果有不会的大家可以去看以下我发的前面几个文章链接我发下面了&#xff0c;各位加油&#xff01; 微信小程序OA会议系统数据交互-CSDN博客 微信小程序会议OA系统其他页面-CSDN博客 …...

Git(一)Windows下安装及使用Git Bash

目录 一、简介1.1 什么是Git&#xff1f;1.2 Git 的主要特点1.3 什么是 Git Bash&#xff1f; 二、下载三、安装3.1 同意协议3.2 选择安装位置3.3 其他配置&#xff08;【Next】 即可&#xff09;3.4 安装完毕3.5 打开 Git Bash 官网地址&#xff1a; https://www.git-scm.com/…...

[AUTOSAR][诊断管理][ECU][$19] 读取ECU的DTC故障信息

一、简介 在车载诊断中常用的诊断协议有ISO 14229等&#xff0c;在协议中主要定义了诊断请求、诊断响应的报文格式及ECU该如何处理诊断请求的应用。其中ISO 14229系列标准协议定义了用于行业内诊断通信的需求规范&#xff0c;也就是UDS。UDS主要应用于OSI七层模型的第七层——…...

前端精度问题 (id 返回的和传给后端的不一致问题)

eg: 后端返回 id 10976458979374929 前端获取到的: 10976458979374928 原因: js 中 Number类型范围-2^53 1 到 2^53 - 1 Number.isSafeInteger()用来判断一个整数是否落在这个范围之内。 java中 Long 类型的取值范围是-2^63 1 到 2^63 - 1, 比JavaScript中大很多&#xff0…...

WPF Material Design UI框架

前言 Material Design in xaml 是开源免费的ui框架&#xff0c;工控软件主打的就是简单界面。 以下简称MD 相关资源 MaterialDesignInXamlToolkit Github 地址 MD 快速启动 MD 案例压缩包 MD 框架使用 启动环境配置 安装Nuget包 App.xaml 配置 <Application x:Class&qu…...

C语言求 3*3 矩阵对角线之和

完整代码&#xff1a; // 求 3*3 矩阵对角线之和 #include<stdio.h>int main() {int n3;int arr[3][3];// 输入矩阵printf("请输入矩阵的元素:\n");for (int i 0; i < n; i){for (int j 0; j < n; j){scanf("%d", &arr[i][j]);}}int su…...

缓存分片中的哈希算法与一致性哈希算法

什么是缓存分片 在高并发场景下&#xff0c;缓存往往成为了瓶颈。这时候&#xff0c;我们可以通过缓存数据分片的方式来解决问题。所谓缓存数据分片&#xff0c;就是将缓存数据按照一定的规则分成多个片段&#xff0c;每个片段由不同的缓存节点负责。这样做有两个好处&#xf…...

线框图软件:Balsamiq Wireframes mac中文介绍

Balsamiq Wireframes mac是一款用于创建线框图的软件工具。它旨在帮助用户快速制作出清晰、简洁的界面原型&#xff0c;以便在设计和开发过程中进行协作和沟通。 Balsamiq Wireframes具有简单直观的用户界面&#xff0c;使用户能够快速添加和编辑各种用户界面元素&#xff0c;如…...

【wxWidgets实现透明wxPanel_核心实现_原创思想】

描述 wxWidgets 根本就没有实现过透明wxPanel容器,你设置wxTRANSPARENT_WINDOW,结果sorry 黑色,哈哈哈哈, 就是和你作对.想想当下那么漂亮的桌面, 背景, 透明, 特效.哎 悲哀啊,实现不了,就那死板的界面特性. 网上找了好久,也是乱七八糟,改底层代码还是算了吧,升级特要命.都是只…...

重大技术问题,iPhone 15 Pro Max面临“烧屏门”风波 | 百能云芯

近期&#xff0c;社交媒体平台上陆续涌现大量用户和数码博主就iPhone 15 Pro Max出现烧屏问题的投诉与评论。 烧屏问题是OLED屏幕常见的一个缺陷&#xff0c;这是由OLED屏幕发光机制引发的&#xff0c;OLED屏幕可视为由无数微小的灯泡-像素点构成&#xff0c;这些像素点可以独立…...

深度学习中的不确定性综述

领域学者&#xff1a; http://www.gatsby.ucl.ac.uk/~balaji/ 论文标题&#xff1a; A Survey of Uncertainty in Deep Neural Networks 论文链接&#xff1a; https://arxiv.org/pdf/2107.03342.pdf 概要 在过去的十年中&#xff0c;神经网络几乎遍及所有科学领域&#x…...

uni-app 小宠物 - 会说话的小鸟

在 template 中 <view class"container"><view class"external-shape"><view class"face-box"><view class"eye-box eye-left"><view class"eyeball-box eyeball-left"><span class"…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...