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

设计模式-创建型模式-原型模式

1.原型模式定义

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

1.1 原型模式优缺点

优点

  • 当创建一个新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程,通过复制一个已有的实例可以提高新实例的创建效率;
  • 相较比工程模式,原型模式提供了简化的创建结构,无需专门的工厂类来创建产品;
  • 可以使用深克隆的方式保存对象状态,辅助实现撤销操作;

缺点

  • 需要为每个类配备一个克隆方法,而且这个克隆方法位于一个类的内部,对已有的类改造时需要修改源代码,违反了开闭原则;

1.2 原型模式适用场景

        创建对象的成本比较大,比如对象中的数据是经过复杂计算或者需要从数据库得到,这种情况就可以使用原型模式,从其他已有的对象中进行拷贝,而不是每次都创建新的对象;

  • 资源优化场景,如当进行对象初始化需要很多外部资源,IO资源、数据文件、CPU、网络、内存等;
  • 复杂的依赖场景,如A对象的创建依赖B,B依赖C,C依赖D。。。
  • 性能和安全要求的场景,如同一个用户在一个会话周期里,可能会反复登录平台或使用某些受限的功能,每一次访问请求都会访问授权服务器进行授权,但如果每次都通过 new 产生一个对象会非常烦琐,这时则可以使用原型模式;
  • 同一个对象可能被多个修改者使用的场景;
  • 需要保存原始状态的场景,如记录历史操作的场景;

2.原型模式原理

        原型模式核心就是通过克隆复制一个对象;

  • 抽象原型类(Prototype):声明克隆方法的接口类,是所有具体原型类的公共父类,它可以是抽象类也可以是接口;
  • 具体原型类(ConcretePrototype):实现在抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象;
  • 客户类(Client):在客户类中使一个原型对象克隆自身从而创建一个新的对象,由于客户类针对抽象原型类编程,因此用户可以根据需要选择具体原型类,系统具有较好的扩展性,增加或者替换原型类都比较方便; 

 

2.1 深克隆与浅克隆

  • 深克隆:完全创建一个新对象,且新对象的变量同原型一致,二者互不影响;
  • 浅克隆:新对象的变量同原型一致,且新对象的引用仍然指向原型对象,二者共享同一对象;

        Java 中的 Object 类的 clone() 方法就是浅克隆;如下面常用的BeanUtils用到了浅克隆;

BeanUtils.cloneBean(Object obj);

         对象序列化之后再进行反序列化获取到的就是不同对象,这就是深克隆;

SerializationUtils.clone(T object);

3.原型模式实现

【实例】

        如一个广告邮件的发送,大部分信息都是用的模板是相同的,只有收件人等不同,如果每发送一个邮件就创建一个邮件对象比较浪费,这就可以用到原型模式;

【代码】

        首先实体类中重写clone()方法

@Data
public class Mail implements Cloneable{//收件人private String receiver;//邮件名称private String subject;//称谓private String appellation;//邮件内容private String context;//构造函数public Mail(AdvTemplate advTemplate) {this.context = advTemplate.getAdvContext();this.subject = advTemplate.getAdvSubject();}@Overridepublic Mail clone(){Mail mail = null;try {mail = (Mail)super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return mail;}
}

        然后即可克隆该对象

//模拟邮件发送
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(9999999);cloneMail.setReceiver(num+"@"+"liuliuqiu.com");//发送 邮件sendMail(cloneMail);i++;
}

相关文章:

设计模式-创建型模式-原型模式

1.原型模式定义 用一个已经创建的实例作为原型&#xff0c;通过复制该原型对象来创建一个和原型对象相同的新对象&#xff1b; 1.1 原型模式优缺点 优点 当创建一个新的对象实例较为复杂时&#xff0c;使用原型模式可以简化对象的创建过程&#xff0c;通过复制一个已有的实例…...

遗传算法与深度学习实战(7)——使用遗传算法解决N皇后问题

遗传算法与深度学习实战&#xff08;7&#xff09;——使用遗传算法解决N皇后问题 0. 前言1. N 皇后问题2. 解的表示3. 遗传算法解决 N 皇后问题小结系列链接 0. 前言 进化算法 (Evolutionary Algorithm, EA) 和遗传算法 (Genetic Algorithms, GA) 已成功解决了许多复杂的设计…...

R语言:如何安装包“linkET”

自己在R语言中安装包“linkET”时报错不存在叫‘linket’这个名字的程辑包 尝试了install.packages("linkET")和BiocManager::install("linkET")两种安装办法都不行 >install.packages("linkET") WARNING: Rtools is required to build R pa…...

JSON, YAML, XML, CSV交互可视化

1、jsoncrack https://jsoncrack.com/editor...

Android UI:PopupWindow:源码分析:设置WindowManager.LayoutParams中的各种参数

文章目录 设置flags是否包含某些flag设置gravity设置type设置softInputMode设置windowAnimations设置width/height设置token 在WindowManager.addView之前设置在WindowManager.addView之后,可通过i熬夜难过update方法设置设置format设置flags是否包含某些flag 1666 …...

MySQL:从入门到放弃

基础查询 MySQL&#xff1a;基础查询 Mybatis&#xff1a;基础巩固-DDL 项目实战 MySQL&#xff1a;按照日期分组查询 查询开始时间与结束时间在指定的日期范围之内&#xff0c;并且结束时间可以为NULL的数据...

C++OpenGL三维显示镜面反射光线漫反射实例

程序示例精选 COpenGL三维显示镜面反射光线漫反射实例 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《COpenGL三维显示镜面反射光线漫反射实例》编写代码&#xff0c;代码整洁&#xff0c;…...

【前端面试】从npm 升级到 pnpm的总结

pnpm优势 pnpm 和 npm 在性能上存在一些明显的差异,这也是一些开发者选择从 npm 切换到 pnpm 的原因。以下是一些关键的差异和原因: 1. 速度: pnpm 比 npm 快了近 2 倍,它通过优化的依赖管理,显著提高了安装速度 。 2. 磁盘空间效率: pnpm 使用基于内容寻址的文件系…...

同步外网YUM源-3

在企业实际应用场景中,仅仅靠光盘里面的RPM软件包是不能满足需要,我们可以把外网的YUM源中的所有软件包同步至本地,可以完善本地YUM源的软件包数量及完整性。 获取外网YUM源软件常见方法包括Rsync、Wget、Reposync,三种同步方法的区别Rsync方式需要外网YUM源支持RSYNC协议…...

Linux的oracle数据库导入其他用户导出的数据库文件

如果用户使用的是expdp的命令&#xff0c;导入就要使用impdp命令&#xff0c;本文以impdp为例进行介绍 1、查看当前创建的所有dmp导出目录 select * from dba_directories 2、为创建的目录赋权限 比如咱们将数据库导入到test用户&#xff0c; grant read,write on directo…...

FLUX.1 文生图模型微调指南

FLUX.1 是 Black Forest Labs 今年夏天发布的文本转图像模型系列。FLUX.1 模型为开源图像生成模型树立了新标准&#xff1a;它们可以生成逼真的手、清晰的文本&#xff0c;甚至可以生成搞笑表情包这样异常困难的任务。 现在&#xff0c;你可以使用 Ostris 的 Replicate 上的 A…...

JavaWeb基础:HTTP协议与Tomcat服务器

目录 1. HTTP协议简介 示例代码&#xff1a;创建HTTP GET请求 2. Tomcat服务器介绍 Tomcat的基本操作 示例代码&#xff1a;部署简单Servlet 3. 使用Servlet处理请求 示例代码&#xff1a;处理POST请求 在现代网络开发中&#xff0c;理解HTTP协议和如何使用Tomcat作为服…...

python井字棋游戏设计与实现

python实现井字棋游戏 游戏规则&#xff0c;有三个井字棋盘&#xff0c;看谁连成的直线棋盘多谁就获胜 棋盘的展现形式为 棋盘号ABC和位置数字1-9 输入A1 代表在A棋盘1号位数下棋 效果图如下 部分源码如下&#xff1a; 卫星工纵浩 白龙码程序设计&#xff0c;点 代码获取 …...

据说是可以和 Windows 一拼的 5个 Linux 发行版

现如今有数以千计的 Linux 发行版可供您使用&#xff0c;然而人们却无法选择一个完美的操作系统来替代 Windows。 使用 Windows 时&#xff0c;傻瓜都能操作自如&#xff0c;同样的方法却不适用于 Linux。在这里&#xff0c;您必须具备操作和使用操作系统的基本知识。因此人们经…...

PHP 常用函数

1. ksort&#xff08;&#xff09; 如果你有一个数组 array&#xff08;[11] > array(XX), [6] > array(YYY)&#xff09;&#xff0c;你想要返回按照key重新排序&#xff0c;并不改变键和值之间的关联&#xff0c;处理之后的结果为 array&#xff08;[6] > array(YY…...

如何将MySQL迁移到TiDB,完成无缝业务切换?

当 MySQL 数据库的单表数据量达到了亿级&#xff0c;会发生什么&#xff1f; 这个现象表示公司的业务上了一个台阶&#xff0c;随着数据量的增加&#xff0c;公司规模也进一步扩大了&#xff0c;是非常喜人的一个改变 &#xff0c;然而随之而来的其他变化&#xff0c;就没那么…...

【嵌入式烧录刷写文件】-2.10-为一个Intel Hex文件计算校验和Checksum

案例背景(共6页精讲): 有如下一段Intel Hex文件&#xff0c;为其创建Checksum校验和&#xff1a;CRC16&#xff0c;CRC32(CVN)&#xff0c;SHA-256 Hash算法…, 将Checksum Value填充到指定地址。 :2091000058595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767…...

整体思想以及取模

前言&#xff1a;一开始由于失误&#xff0c;误以为分数相加取模不能&#xff0c;但是其实是可以取模的 这个题目如果按照一般方法&#xff0c;到达每个节点再进行概率统计&#xff0c;但是不知道为什么只过了百分之十五的测试集 题目地址 附上没过关的代码 #include<bits…...

RabbitMQ 消息可靠保障

RabbitMQ 消息可靠保障 消息的可靠性保证生产者重连生产者确认解决思路A-确认机制解决思路B-备份交换机 MQ 服务器宕机导致消息丢失消费端消息的可靠性保障 消费端限流给消息生成唯一id 消息的可靠性保证 实际项目中 MQ 的流程一般是&#xff1a;生产端把消息路由到交换机&…...

Redis 作为 PHP 的会话存储

使用 Redis 作为 PHP 的会话存储&#xff0c;可以实现多个服务器之间的会话共享&#xff0c;提高会话管理的效率&#xff0c;特别是在分布式系统中。这种方法将会话数据存储在 Redis 中&#xff0c;而不是使用默认的文件系统&#xff0c;从而使多个服务器可以访问相同的会话数据…...

基于Simulink的自抗扰控制(ADRC)在OBC前级的应用

手把手教你学Simulink——基于Simulink的自抗扰控制(ADRC)在OBC前级的应用​ (附:OBC前级拓扑剖析+ADRC抗扰原理+TD/ESO/NLSEF算法推导+Simulink全模型搭建+动态响应/谐波抑制对比+实机部署指南) 摘要​ 车载充电机(OBC)前级作为交流-直流(AC-DC)整流核心,需将电网…...

如何快速配置Windows三指拖动功能:ThreeFingerDragOnWindows完整指南

如何快速配置Windows三指拖动功能&#xff1a;ThreeFingerDragOnWindows完整指南 【免费下载链接】ThreeFingersDragOnWindows Enables macOS-style three-finger dragging functionality on Windows Precision touchpads. 项目地址: https://gitcode.com/gh_mirrors/th/Thre…...

避坑指南:pyzbar识别模糊二维码的5种图像预处理技巧(Python+OpenCV)

提升pyzbar识别率&#xff1a;5种图像预处理技术解决模糊二维码难题 1. 模糊二维码识别的核心挑战 在现实应用中&#xff0c;二维码识别经常遇到各种图像质量问题。我曾在一个物流仓储项目中亲眼目睹&#xff0c;由于包装反光和运输磨损&#xff0c;标准识别流程的失败率高达40…...

C语言实战:构建嵌入式eMMC RPMB安全读写组件

1. eMMC RPMB分区基础解析 我第一次接触RPMB分区是在开发智能门锁项目时&#xff0c;需要存储指纹特征码等敏感数据。传统存储方式容易被篡改&#xff0c;而RPMB完美解决了这个问题。RPMB&#xff08;Replay Protected Memory Block&#xff09;是eMMC芯片中的特殊安全存储区域…...

OpenMV串口数据收发实战:如何与Arduino/STM32稳定通信并解析指令

OpenMV与微控制器串口通信实战&#xff1a;从基础协议到工业级稳定性优化 在智能机器人、自动化检测设备等嵌入式视觉系统中&#xff0c;OpenMV常作为"视觉传感器"与主控微控制器&#xff08;如Arduino/STM32&#xff09;协同工作。我曾参与过一个AGV小车项目&#x…...

DDS信号发生器设计避坑指南:基于FPGA的AD9767驱动常见问题与优化技巧

FPGA驱动AD9767实战避坑手册&#xff1a;从时序优化到DDS精度提升的进阶技巧 当你在深夜调试FPGA与AD9767的接口时&#xff0c;示波器上那些不规则的毛刺和频率偏差是否曾让你抓狂&#xff1f;作为一款经典的高速14位DAC芯片&#xff0c;AD9767在信号发生、通信系统等领域应用广…...

零基础如何用罗技鼠标宏实现绝地求生自动压枪?高效配置指南

零基础如何用罗技鼠标宏实现绝地求生自动压枪&#xff1f;高效配置指南 【免费下载链接】logitech-pubg PUBG no recoil script for Logitech gaming mouse / 绝地求生 罗技 鼠标宏 项目地址: https://gitcode.com/gh_mirrors/lo/logitech-pubg 你是否在《绝地求生》中因…...

HALCON实战:从一维码到复杂OCR,图像增强与运算的工业视觉全流程解析

1. 工业视觉检测的挑战与HALCON解决方案 在自动化产线上&#xff0c;产品表面的一维码、二维码和字符识别是质量控制的关键环节。我曾在某电子元件生产线遇到这样的场景&#xff1a;传送带以每秒3米的速度移动&#xff0c;产品表面既有激光刻印的微小点阵字符&#xff0c;又有喷…...

如何实现格式保留翻译?Hunyuan MT1.5结构化文本处理实战解析

如何实现格式保留翻译&#xff1f;Hunyuan MT1.5结构化文本处理实战解析 1. 引言&#xff1a;当翻译遇到格式难题 你有没有遇到过这样的尴尬场景&#xff1f;好不容易找到一款翻译工具&#xff0c;把英文网页翻译成了中文&#xff0c;结果发现所有链接都失效了&#xff0c;排…...

丹青识画GPU算力优化部署教程:显存占用降低40%实操

丹青识画GPU算力优化部署教程&#xff1a;显存占用降低40%实操 1. 引言&#xff1a;当艺术邂逅算力&#xff0c;如何优雅地“瘦身”&#xff1f; 想象一下&#xff0c;你刚部署好一个能看懂画作、还能用书法题诗的AI应用——“丹青识画”。它融合了前沿的多模态AI与东方美学&…...