【创建模式-蓝本模式(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基本使用 有两个参数,第一个是要代理的对象,第二个是捕获器,在不知道捕获器使用哪个之前可以先传个空对象。就会启用默认的捕获…...
ChanlunX缠论插件:5分钟快速掌握专业级股市技术分析
ChanlunX缠论插件:5分钟快速掌握专业级股市技术分析 【免费下载链接】ChanlunX 缠中说禅炒股缠论可视化插件 项目地址: https://gitcode.com/gh_mirrors/ch/ChanlunX 想要在复杂多变的股市中精准把握买卖时机吗?ChanlunX缠论插件将深奥的缠中说禅…...
vLLM-v0.17.1实战体验:3步搭建大模型API服务,实测推理速度翻倍
vLLM-v0.17.1实战体验:3步搭建大模型API服务,实测推理速度翻倍 1. vLLM框架简介与核心优势 vLLM是一个专为大语言模型推理优化的高性能服务框架,由加州大学伯克利分校Sky Computing Lab开发并开源。最新发布的v0.17.1版本在推理速度、内存管…...
缩空气储能和释能阶段模型➕相关文档文献。 建立了压缩空气储能系统中的压缩机、换热器、储气罐、透平、热水罐等设备的数学模型、 并在 Simulink仿真平台上
压缩空气储能和释能阶段模型➕相关文档文献。 建立了压缩空气储能系统中的压缩机、换热器、储气罐、透平、热水罐等设备的数学模型、 并在 Simulink仿真平台上、 按模块化建模方式完成了系统相关程序编写和仿真模型建立、 包含储能和释能两个阶段的模型压缩空气储能(…...
高通Camera开发实战:ION内存与DMA-BUF的跨进程共享机制详解
高通Camera开发实战:ION内存与DMA-BUF的跨进程共享机制详解 在移动影像系统的开发中,内存管理始终是性能优化的核心战场。当Camera HAL层需要处理4K60fps视频流或超高分辨率连拍时,传统的内存拷贝方式会带来难以忍受的性能损耗。ION内存分配器…...
从Ingress到Rancher面板:一次搞定K8s服务暴露与多集群管理平台部署
Kubernetes服务暴露与多集群管理实战:从Ingress到Rancher全链路部署 当企业级容器化应用规模扩大时,如何安全高效地暴露服务并实现多集群统一管理成为技术团队面临的核心挑战。本文将带您深入探索从Ingress控制器配置到Rancher管理平台部署的完整技术链路…...
springboot 微信小程序的红色导览之烈士陵园烈士纪念app
目录同行可拿货,招校园代理 ,本人源头供货商功能模块设计交互功能设计后台管理功能特色辅助功能项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 ,本人源头供货商 功能模块设计 用户管理模块 提供微信授…...
前端团队协作:别让沟通成本拖垮你的项目
前端团队协作:别让沟通成本拖垮你的项目 什么是前端团队协作? 前端团队协作是指前端开发团队成员之间的协调与配合,包括代码管理、任务分配、沟通交流等方面。别以为前端开发只是写代码,团队协作不好,项目就会变成一场…...
单片机课设避坑指南:用Proteus 8.0+AT89C51搞定超声波测距仿真(附完整源码)
单片机课设避坑指南:Proteus 8.0AT89C51超声波测距仿真实战 第一次用Proteus做超声波测距仿真时,我在实验室熬了三个通宵——SRF04模块死活测不出距离,LCD1602显示乱码,报警阈值设置总出错。如果你正在为课设发愁,这份…...
《短剧平台商品详情页前端性能优化实战》
🎭 《短剧平台商品详情页前端性能优化实战》背景:短剧平台(如 ReelShort、河马剧场等)的商品详情页(PDP)本质是“内容即商品”。用户路径为:刷剧 → 遇到付费节点 → 购买整部剧/解锁单集。核心…...
使用 HTML + JavaScript 实现组织架构图
文章目录一、组织架构图二、效果演示三、系统分析1.页面结构1.1 操作区域1.2 组织结构图区域2 核心功能实现2.1 数据结构定义2.2 节点渲染逻辑2.3节点展开/收起功能2.4 全部展开/收起四、扩展建议五、完整代码一、组织架构图 在企业管理系统或团队协作平台中,组织结…...
