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

news/2024/9/18 2:11:37/ 标签: 设计模式, 原型模式

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++;
}

http://www.ppmy.cn/news/1515996.html

相关文章

关闭IDEA启动画面

新版IDEA启动时启动画面居中且无法最小化&#xff0c;所以想把它给隐藏掉。&#xff08;此操作不会加快启动速度&#xff09; 在快捷方式后加入参数 nosplash&#xff0c;记得有个空格。

【Python脚本】爬取网络小说

原文链接&#xff1a;https://www.cnblogs.com/aksoam/p/18378309 作为重度小说爱好者, 小说下载网站经常被打击,比如:笔趣阁,奇书网,爱书网,80电子书.这些网站的下载链接经常会失效, 所以, 我想自己动手写一个爬虫程序, 抓取网络小说, 并下载到本地. 给出两种思路的python脚…

ShareSDK 企业微信

本篇文档主要讲解如何使用企业微信并进行分享和授权。 创建应用 登录企业微信并通过企业认证。选择应用管理 > 应用 >创建应用。编辑应用信息。配置授权登录信息。 以下为创建过程示例&#xff0c;图中信息仅为示例&#xff0c;创建时请按照真实信息填写&#xff0c;否…

紧跟大模型技术趋势,为更大更通用的大模型提供底层支撑!关于智能计算系统:从深度学习到大模型,全新版本,发布!

文章目录 &#x1f4cb;前言&#x1f3af; 关于智能计算系统&#x1f3af; 内容简介&#x1f3af; 作者简介&#x1f3af; 专家推荐&#x1f3af; 目录大纲&#x1f525; 参与方式 &#x1f4cb;前言 “只要你想把大模型做得更好、做得更大、做得更快、做得更省电&#xff0c;…

如何正确使用static、class、abstract方法二

如何正确使用static、class、abstract方法 ####How methods work in Python A method is a function that is stored as a class attribute. You can declare and access such a function this way: ####方法在Python中是如何工作的 方法就是一个函数&#xff0c;它作为一个类…

膨胀罐的安装注意事项

1、膨胀罐在热力系统中如空调、锅炉、热泵等一般安装在系统的回水端&#xff1b; 2、膨胀罐在供水系统一般装在水泵的出口。 3、膨胀罐在太阳能承压循环系统中一般安装在水泵的进口附近。 膨胀罐的原理&#xff1a; 当外界有压力的水进入膨胀罐气囊内时&#xff0c;密封在罐内的…

【C#】【EXCEL】Bumblebee/Classes/ExGraphic.cs

Bumblebee/Classes/ExGraphic.cs Flow diagram 根据您提供的代码和要求&#xff0c;我将创建一个流程图来展示ExGraphic类的结构。这个流程图将使用中英双语标注&#xff0c;并对应到代码中的英文。 #mermaid-svg-TRwsnkAxI5mhmCmk {font-family:"trebuchet ms",ve…

数学建模学习(118):牛顿冷却定律的原理解析、案例分析与Python求解

介绍来源:2020全国大学生数学建模竞赛论文展示(A070) ,这里我们详细完整的对该优秀论文的方法进行学习和实践。 文章目录 1. 牛顿冷却定律的定义2. 牛顿冷却定律公式3. 牛顿冷却定律的推导4. 牛顿冷却定律的应用方法5. 牛顿冷却定律的验证6. 牛顿冷却定律的图形7. 案例一7.…

建筑楼宇电气安全与能效管理

随着建筑业的发展&#xff0c;配电系统在楼宇建筑特别是高层建筑中的比重也随之加大。现代的建筑的功能越来越完善&#xff0c;变配电工程、空调工程、机电工程、电梯工程、消防工程等工程设施设备与建筑体相结合&#xff0c;敷设的电气线路变得更为复杂&#xff0c;火灾隐患明…

使用Dotween制作按钮弹性动画效果

效果&#xff1a; 方式&#xff1a; 优点&#xff0c;不需要写任何代码、稳定、可自定义效果

AutoGPT开源项目解读

AutoGPT开源项目解读 (qq.com) AutoGPT旨在创建一个自动化的自我改进系统&#xff0c;能够自主执行和学习各种任务 项目基本信息 首先阅读项目的README.md&#xff0c;下述代理和智能体两个名词可互换 项目简介&#xff1a;一个创建和运行智能体的工具&#xff0c;这些智能体…

C++的模板

文章目录 教学一1. 函数模板定义和使用注意事项 2. 类模板定义和使用注意事项 3. 模板特化全特化偏特化 4. 模板参数非类型参数模板模板参数 5. SFINAE&#xff08;Substitution Failure Is Not An Error&#xff09;示例 6. 模板的高级特性6.1 变长模板参数包&#xff08;Vari…

【解决问题】linux系统运行程序可以打印信息到屏幕,重定向到一个文件,文件中没有信息

在Linux系统中运行程序时&#xff0c;如果你发现程序打印的信息无法通过重定向写入到文件中&#xff0c;那么很可能是因为程序将信息打印到了标准错误流&#xff08;stderr&#xff09;&#xff0c;而不是标准输出流&#xff08;stdout&#xff09;。重定向操作通常只对标准输出…

变声器免费的直接说话的那种!不整虚的,一键变声!好听!

听说网络上一堆推荐软件测评的&#xff0c;一半斗志推销自己家的软件&#xff0c;好不好用其次&#xff0c;关键是名声已经在外&#xff01;今天俺老孙也不整这些虚的&#xff0c;直接上干货&#xff0c;测评2024最新的电脑变声软件&#xff0c;帮助大家了解这六款国内外不同系…

OpenCV几何图像变换(6)计算反转仿射变换函数invertAffineTransform()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 反转一个仿射变换。 该函数计算由 23 矩阵 M 表示的逆仿射变换&#xff1a; [ a 11 a 12 b 1 a 21 a 22 b 2 ] \begin{bmatrix} a_{11} & a…

接口如何设计

在企业中&#xff0c;前后端分离开发是一种常见的开发模式。在这种模式下&#xff0c;Java 程序员通常负责设计和实现后端 API 接口&#xff0c;而前端工程师则根据这些接口来开发用户界面和功能。 首先明确该接口是一个前后端交互接口&#xff0c;该接口由前端通过HTTP协议进…

第2章 C语言基础知识

第2章 C语言基础知识 1.printf()函数 在控制台输出数据&#xff0c;需要使用输出函数&#xff0c;C语言常用的输出函数为printf()。 printf()函数为格式化输出函数&#xff0c;其功能是按照用户指定的格式将数据输出到屏幕上。 printf(“格式控制字符串”,[输出列表]); 格式控…

Ruby Web服务开发:构建高效RESTful API的秘诀

标题&#xff1a;Ruby Web服务开发&#xff1a;构建高效RESTful API的秘诀 Ruby作为一种灵活、高效的编程语言&#xff0c;通过其丰富的库和框架&#xff0c;为开发Web服务提供了强大的支持。本文将深入探讨如何在Ruby中开发Web服务&#xff0c;特别是RESTful API。我们将从基…

[JAVA]什么是泛型?泛型在Java中的应用

目录 1.初识泛型的应用 2.创建自定义泛型类 3.利用较小范围的泛型方法定义 4.了解泛型通配符&#xff0c;什么是泛型通配符&#xff1f; 1.初识泛型的应用 —所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。 —定…

前端宝典十六:深入浅出8大设计模式

本文主要探讨前端开发中的各种设计模式&#xff0c;主要分类有&#xff1a; 单例模式建造者模式代理模式装饰器模式适配器模式策略模式观察者模式发布订阅模式 通过对他们实际开发中的使用场景的解析&#xff0c;深入浅出的一起更全面直观的进行学习&#xff1a; 一、单例模…