【创建模式-蓝本模式(Prototype Pattern)】
目录
- Overview
- 应用场景
- 代码演示
- JDK Prototype pattern
- 更优实践
- 泛型克隆接口
https://doc.hutool.cn/pages/Cloneable/#%E6%B3%9B%E5%9E%8B%E5%85%8B%E9%9A%86%E7%B1%BB
The prototype pattern is a creational design pattern in software development. It is used when the types of objects to create is determined by a prototypical instance, which is cloned to produce new objects. This pattern is used to avoid subclasses of an object creator in the client application, like the factory method pattern does, and to avoid the inherent cost of creating a new object in the standard way (e.g., using the ‘new’ keyword) when it is prohibitively expensive for a given application.
To implement the pattern, the client declares an abstract base class that specifies a pure virtual clone() method. Any class that needs a “polymorphic constructor” capability derives itself from the abstract base class, and implements the clone() operation.
The client, instead of writing code that invokes the “new” operator on a hard-coded class name, calls the clone() method on the prototype, calls a factory method with a parameter designating the particular concrete derived class desired, or invokes the clone() method through some mechanism provided by another design pattern.
The mitotic division of a cell — resulting in two identical cells — is an example of a prototype that plays an active role in copying itself and thus, demonstrates the Prototype pattern. When a cell splits, two cells of identical genotype result. In other words, the cell clones itself.[1]
Overview
The prototype design pattern is one of the 23 Gang of Four design patterns that describe how to solve recurring design problems to design flexible and reusable object-oriented software, that is, objects that are easier to implement, change, test, and reuse.[2]: 117
The prototype design pattern solves problems like:[3]
- How can objects be created so that the specific type of object can be determined at runtime?
- How can dynamically loaded classes be instantiated?
Creating objects directly within the class that requires (uses) the objects is inflexible because it commits the class to particular objects at compile-time and makes it impossible to specify which objects to create at run-time.
The prototype design pattern describes how to solve such problems:
- Define a Prototype object that returns a copy of itself.
- Create new objects by copying a Prototype object.
This enables configuration of a class with different Prototype objects, which are copied to create new objects, and even more, Prototype objects can be added and removed at run-time.
See also the UML class and sequence diagram below.
应用场景
当需要反复构建出同一个类的大量实例,并且这些实例的初始状态都是一样的时候就可以先通过new创建出一个实例,对该实例进行调整(通常就是设置一些参数),这个实例就可以称之为原型,这也是该设计模式叫原型模式的缘由。
我们可以举一个实际的例子(引用自:《设计模式之禅道》),银行批量向客户发送节日邮件,假设一封邮件包括:①称呼、②节日祝福语;那么操作流程应该是这样的:
- 创建一个模板,对该模板设置节日祝福语,因为所有的人节日祝福语是相同的;
- 为每一个客户依次克隆一个第一步的模板(如果不新建模板的话,多线程并发时是不安全的,通过new创建效率不如克隆),得到一个实例,将该实例传递给一个发送邮件线程;
- 发送线程对传递得到的邮件实例,进行称呼设置,然后进行邮件发送;
代码演示
JDK Prototype pattern
/*** 原型模式 VS 构造函数 性能测试** @author hipilee*/
public class JdkCloneable implements Cloneable {public int properties1 = 0;public JdkCloneable() {}public JdkCloneable(int properties1) {HashMap<Integer, Integer> hashMap = new HashMap(100);for (int i = 0; i < 10; i++) {hashMap.put(properties1, properties1);}}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}public static void main(String[] args) throws CloneNotSupportedException {long start, end;start = System.currentTimeMillis();JdkCloneable jdkCloneable = new JdkCloneable(1000);for (int i = 0; i < 10000000; i++) {jdkCloneable.clone();}end = System.currentTimeMillis();System.out.println("原型模式:耗时" + (end - start) / 1000.0 + "毫秒。");start = System.currentTimeMillis();for (int j = 0; j < 10000000; j++) {new JdkCloneable();}end = System.currentTimeMillis();System.out.println("默认构造:耗时" + (end - start) / 1000.0 + "毫秒。");start = System.currentTimeMillis();for (int j = 0; j < 10000000; j++) {new JdkCloneable(j);}end = System.currentTimeMillis();System.out.println("复杂构造:耗时" + (end - start) / 1000.0 + "毫秒。");}
}
输出:
原型模式:耗时0.357毫秒。
简单构造:耗时0.008毫秒。
复杂构造:耗时6.016毫秒。
由此我们可以得出,原型模式相对于new关键字构造对象的优势在于:如果new构造调用的构造函数比较耗时时,原型模式才有明显优势;因为原型模式是从内存中拷贝二进制数据不会调用构造函数。
更优实践
通过使用Hutool工具类,来解决jdk自身的Cloneable接口不方便的地方:
- java.lang.Cloneable接口是个空接口起标记作用,在对类进行克隆时,如果该类只是实现了java.lang.Cloneable接口并没有重写Object的clone()函数,那么会抛出CloneNotSupportedException异常;
- Object的clone()函数返回的对象是Object,克隆后需要程序员自己强转下类型;
- jdk的克隆函数是浅拷贝
泛型克隆接口
实现Hutool的cn.hutool.core.clone.Cloneable接口。此接口定义了一个返回泛型的成员方法,这样,实现此接口后会提示必须实现一个public的clone方法,调用父类clone方法即可:
import cn.hutool.core.clone.CloneRuntimeException;
import cn.hutool.core.clone.Cloneable;/*** 猫猫类,使用实现Cloneable方式* @author Looly**/
class Cat implements Cloneable<Cat>{private String name = "miaomiao";private int age = 2;@Overridepublic Cat clone() {try {return (Cat) super.clone();} catch (CloneNotSupportedException e) {throw new CloneRuntimeException(e);}}
}
相关文章:
【创建模式-蓝本模式(Prototype Pattern)】
目录 Overview应用场景代码演示JDK Prototype pattern 更优实践泛型克隆接口 https://doc.hutool.cn/pages/Cloneable/#%E6%B3%9B%E5%9E%8B%E5%85%8B%E9%9A%86%E7%B1%BB The prototype pattern is a creational design pattern in software development. It is used when the t…...
Spring Boot应用开发深度解析与实战案例
Spring Boot应用开发深度解析与实战案例 在当今快速发展的软件开发领域,Spring Boot凭借其“约定优于配置”的理念,极大地简化了Java应用的开发、配置和部署过程,成为了微服务架构下不可或缺的技术选型。本文将深入探讨Spring Boot的核心特性、最佳实践,并通过一个具体的…...
优化Go语言中的网络连接:设置代理超时参数
网络连接优化的重要性 在分布式系统和微服务架构中,网络请求的效率直接影响到整个系统的响应速度。合理的超时设置可以防止系统在等待网络响应时陷入无限期的阻塞,从而提高系统的吞吐量和用户体验。特别是在使用代理服务器时,由于增加了网络…...
《神经网络与深度学习》(邱锡鹏) 内容概要【不含数学推导】
第1章 绪论 基本概念:介绍了人工智能的发展历程及不同阶段的特点,如符号主义、连接主义、行为主义等。还阐述了深度学习在人工智能领域的重要地位和发展现状,以及其在图像、语音、自然语言处理等多个领域的成功应用。术语解释 人工智能&…...
原创 传奇996_55——后端如何点击npc隐藏主界面
点击图片退出,举例: |linkexit Img|ax0.5|ay0.5|percentx50|percenty50|imgpublic/touming2.png|hideMain1|linkexit <Img|x0|y0|esc1|show4|bg1|move0|imgcustom/new/longhun/bg.png|loadDelay0|reset1|hideMain1>...
RabbitMQ中的Work Queues模式
在现代分布式系统中,消息队列(Message Queue)是实现异步通信和解耦系统的关键组件之一。RabbitMQ 是一个广泛使用的开源消息代理软件,支持多种消息传递模式。其中,Work Queues(工作队列)模式是一…...
GESP202412 四级【Recamán】题解(AC)
》》》点我查看「视频」详解》》》 [GESP202412 四级] Recamn 题目描述 小杨最近发现了有趣的 Recamn 数列,这个数列是这样生成的: 数列的第一项 a 1 a_1 a1 是 1 1 1;如果 a k − 1 − k a_{k-1}-k ak−1−k 是正整数并且没有在数…...
蓝桥杯新年题解 | 第15届蓝桥杯迎新篇
蓝桥杯新年题解 | 第15届蓝桥杯迎新篇 2024年的蓝桥杯即将拉开序幕!对于许多编程爱好者来说,这不仅是一次展示自我能力的舞台,更是一次学习和成长的机会。作为一名大一新生的小蓝,对蓝桥杯充满了期待,但面对初次参赛的…...
3D 生成重建035-DiffRF直接生成nerf
3D 生成重建035-DiffRF直接生成nerf 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 本文提出了一种基于渲染引导的三维辐射场扩散新方法DiffRF,用于高质量的三维辐射场合成。现有的方法通常难以生成具有细致纹理和几何细节的三维模型,并且容易出…...
@SpringBootTest 报错: UnsatisfiedDependencyException
Spring Boot Test 报错: UnsatisfiedDependencyException 在使用 SpringBootTest 测试时,出现 UnsatisfiedDependencyException 报错,原因和解决方法如下。 报错原因分析 1. Spring 存在涉及 Bean 没有被添加 Spring Boot 测试中,默认会加…...
mysql、postgresql、oceanbase调优
一、mysql 1、my.cnf [mysqld_safe] log-error=/data/mysql/log/mysql.log pid-file=/data/mysql/run/mysqld.pid[client] socket=/data/mysql/run/mysql.sock default-character-set=utf8[mysqld] basedir=/usr/local/mysql tmpdir=/data/mysql/tmp datadir=/data/mysql/dat…...
MySQL 数据库事务实践
引言 在现代应用程序开发中,确保数据库操作的完整性和一致性至关重要。MySQL 提供了强大的事务管理功能,允许开发者以原子性、一致性、隔离性和持久性(ACID)的方式处理数据。本文将通过详细的解释和实际示例,带你深入…...
VScode、Windsurf、Cursor 中 R 语言相关快捷键设置
前言 在生物信息学数据分析中,R语言是一个不可或缺的工具。为了提高R语言编程效率,合理设置快捷键显得尤为重要。本文介绍在VSCode Windsurf Cursor 中一些实用的R语言快捷键设置,让非 Rstudio 的 IDE 用起来得心应手😑 操作种…...
tcpdump编译
https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz tar -zxvf flex-2.6.4.tar.gz ./configure CFLAGS-D_GNU_SOURCE make sudo make installwget http://ftp.gnu.org/gnu/bison/bison-3.2.1.tar.gz ./configure make sudo make install以上两个库是…...
Linux下禁止root远程登录访问
开始讲故事 Long long ago, Linux远程访问方式有telnet、ssh两种协议;有人可能还会说vnc和rdp协议方式,后面这两种主要是可视化桌面场景下的,并非主流。 时过境迁,telnet因安全性低逐渐被禁用淘汰,最后就…...
算法刷题Day16: BM41 输出二叉树的右视图
题目链接 描述 思路: 递归构造二叉树在Day15有讲到。复习一下,就是使用递归构建左右子树。将中序和前序一分为二。 接下来是找出每一层的最右边的节点,可以利用队列层次遍历。 利用队列长度记录当前层有多少个节点,每次从队列里…...
登录授权的实现:json web token + redis + springboot
文章目录 引言I token实现思路传统JWT TOKEN认证方式改进的JWT TOKEN认证方式redis设计II java代码实现登录接口退出登录接口登录之后接口(token解析和校验)III 常见问题400引言 应用场景: 登录认证 I token实现思路 传统JWT TOKEN认证方式 RESTful API TOKEN认证方式:…...
yolov,coco,voc标记的睡岗检测数据集,可识别在桌子上趴着睡,埋头睡觉,座椅上靠着睡,平躺着睡等多种睡姿的检测,6549张图片
yolov,coco,voc标记的睡岗检测数据集,可识别在桌子上趴着睡,埋头睡觉,座椅上靠着睡,平躺着睡等多种睡姿的检测,6549张图片 数据集分割 6549总图像数 训练组91% 5949图片 有效集9&#x…...
数据库表的CRUD
SQL语句(Structured Query Language)是用于与关系型数据库进行交互的语言。下面是几个常用的SQL语句: 创建表: CREATE TABLE table_name ( column1 datatype, column2 datatype, column3 datatype, ... ); 插入数据: …...
Proxy与Reflect
监听对象操作 在Object中,可以通过defineProperty中的get,set进行监听, Proxy基本使用 有两个参数,第一个是要代理的对象,第二个是捕获器,在不知道捕获器使用哪个之前可以先传个空对象。就会启用默认的捕获…...
GIS实战:栅格数据属性表灰色问题的三大解决方案
1. 栅格数据属性表“变灰”的烦恼,你遇到过吗? 嘿,朋友们,今天咱们来聊聊GIS处理中一个挺常见但又让人有点头疼的小麻烦——栅格数据的属性表“变灰”了。我猜,如果你正在处理土地利用分类图、NDVI植被指数图ÿ…...
flink-yarn提交任务,application无限次appattempt
一般大家都推荐配置yarn.resourcemanager.am.max-attempts、yarn.application-attempt-failures-validity-interval和yarn.application-attempts 但是在yarn-site.xml里配置了却没生效哈哈 不生效的原因是因为flink提交application 时候fink会通过反射给yarn传过去,…...
Openclaw玩转高德地图
🗺️ 通过本文可以满足类似如下需求 五一计划到昆明游玩,使用高德制作4天旅行攻略。同时将生成的旅行攻略发到钉钉群里,以满足行中探店、导航、打车、购票等出行需求。如下图所示: 用到了钉钉,Openclaw的对接可以参考前文https://blog.csdn.net/s060403072/article/deta…...
Vue3组件化架构终极指南:新蜂商城插件系统深度解析
Vue3组件化架构终极指南:新蜂商城插件系统深度解析 【免费下载链接】newbee-mall-vue3-app 🔥 🎉Vue3 全家桶 Vant 搭建大型单页面商城项目,新蜂商城 Vue3.2 版本,技术栈为 Vue3.2 Vue-Router4.x Pinia Vant4.x。 …...
读懂 ABAP 中的 tag interface:从语义标记到运行时契约的设计逻辑
很多开发者一看到 interface,脑海里浮现的往往都是方法列表、参数签名、异常定义这些典型的面向对象合同。不过在 ABAP 世界里,interface 还有一类非常特殊的存在:它几乎不强调业务方法本身,却会直接影响 ABAP runtime framework 和编译器如何看待一个类。这类接口,就是 t…...
php结婚网系统的设计与实现毕业论文
目录摘要引言系统需求分析系统设计系统实现系统测试总结与展望参考文献附录(可选)项目技术支持源码LW获取详细视频演示 :文章底部获取博主联系方式!同行可合作摘要 简要介绍系统开发背景、目的、技术栈及创新点。 引言 阐述婚恋…...
Guanaco模型的安全对齐:QLoRA微调中的价值观注入
Guanaco模型的安全对齐:QLoRA微调中的价值观注入 【免费下载链接】qlora QLoRA: Efficient Finetuning of Quantized LLMs 项目地址: https://gitcode.com/gh_mirrors/ql/qlora QLoRA(Quantized Low-Rank Adaptation)作为高效微调量化…...
nlp_structbert_sentence-similarity_chinese-large代码实例:扩展支持CSV批量句子对相似度计算
nlp_structbert_sentence-similarity_chinese-large代码实例:扩展支持CSV批量句子对相似度计算 你是不是也遇到过这样的问题?手里有一大堆句子对,需要批量计算它们的相似度,但一个个手动输入太麻烦,用脚本处理又得写一…...
AI辅助开发实战:基于CosyVoice Fish-Speech构建高效语音合成系统
最近在做一个需要大量语音合成的项目,之前用的一些开源方案,要么合成速度慢得让人着急,要么音质忽高忽低,资源占用还特别大。为了解决这些问题,我花了不少时间研究,最终选择了 CosyVoice 和 Fish-Speech 这…...
一文讲透|9个降AIGC平台测评:本科生降AI率必备指南
在当今学术写作中,AI生成内容(AIGC)的广泛应用让越来越多的本科生面临“AI痕迹过重”和“查重率过高”的双重挑战。无论是课程论文、毕业设计还是科研项目,如何有效降低AI痕迹,同时保持文章逻辑清晰、语言自然…...
