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

【创建模式-蓝本模式(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创建出一个实例,对该实例进行调整(通常就是设置一些参数),这个实例就可以称之为原型,这也是该设计模式叫原型模式的缘由。

  我们可以举一个实际的例子(引用自:《设计模式之禅道》),银行批量向客户发送节日邮件,假设一封邮件包括:①称呼、②节日祝福语;那么操作流程应该是这样的:

  1. 创建一个模板,对该模板设置节日祝福语,因为所有的人节日祝福语是相同的;
  2. 为每一个客户依次克隆一个第一步的模板(如果不新建模板的话,多线程并发时是不安全的,通过new创建效率不如克隆),得到一个实例,将该实例传递给一个发送邮件线程;
  3. 发送线程对传递得到的邮件实例,进行称呼设置,然后进行邮件发送;

代码演示

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语言中的网络连接:设置代理超时参数

网络连接优化的重要性 在分布式系统和微服务架构中&#xff0c;网络请求的效率直接影响到整个系统的响应速度。合理的超时设置可以防止系统在等待网络响应时陷入无限期的阻塞&#xff0c;从而提高系统的吞吐量和用户体验。特别是在使用代理服务器时&#xff0c;由于增加了网络…...

《神经网络与深度学习》(邱锡鹏) 内容概要【不含数学推导】

第1章 绪论 基本概念&#xff1a;介绍了人工智能的发展历程及不同阶段的特点&#xff0c;如符号主义、连接主义、行为主义等。还阐述了深度学习在人工智能领域的重要地位和发展现状&#xff0c;以及其在图像、语音、自然语言处理等多个领域的成功应用。术语解释 人工智能&…...

原创 传奇996_55——后端如何点击npc隐藏主界面

点击图片退出&#xff0c;举例&#xff1a; |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模式

在现代分布式系统中&#xff0c;消息队列&#xff08;Message Queue&#xff09;是实现异步通信和解耦系统的关键组件之一。RabbitMQ 是一个广泛使用的开源消息代理软件&#xff0c;支持多种消息传递模式。其中&#xff0c;Work Queues&#xff08;工作队列&#xff09;模式是一…...

GESP202412 四级【Recamán】题解(AC)

》》》点我查看「视频」详解》》》 [GESP202412 四级] Recamn 题目描述 小杨最近发现了有趣的 Recamn 数列&#xff0c;这个数列是这样生成的&#xff1a; 数列的第一项 a 1 a_1 a1​ 是 1 1 1&#xff1b;如果 a k − 1 − k a_{k-1}-k ak−1​−k 是正整数并且没有在数…...

蓝桥杯新年题解 | 第15届蓝桥杯迎新篇

蓝桥杯新年题解 | 第15届蓝桥杯迎新篇 2024年的蓝桥杯即将拉开序幕&#xff01;对于许多编程爱好者来说&#xff0c;这不仅是一次展示自我能力的舞台&#xff0c;更是一次学习和成长的机会。作为一名大一新生的小蓝&#xff0c;对蓝桥杯充满了期待&#xff0c;但面对初次参赛的…...

3D 生成重建035-DiffRF直接生成nerf

3D 生成重建035-DiffRF直接生成nerf 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 本文提出了一种基于渲染引导的三维辐射场扩散新方法DiffRF&#xff0c;用于高质量的三维辐射场合成。现有的方法通常难以生成具有细致纹理和几何细节的三维模型&#xff0c;并且容易出…...

@SpringBootTest 报错: UnsatisfiedDependencyException

Spring Boot Test 报错: UnsatisfiedDependencyException 在使用 SpringBootTest 测试时&#xff0c;出现 UnsatisfiedDependencyException 报错&#xff0c;原因和解决方法如下。 报错原因分析 1. Spring 存在涉及 Bean 没有被添加 Spring Boot 测试中&#xff0c;默认会加…...

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 数据库事务实践

引言 在现代应用程序开发中&#xff0c;确保数据库操作的完整性和一致性至关重要。MySQL 提供了强大的事务管理功能&#xff0c;允许开发者以原子性、一致性、隔离性和持久性&#xff08;ACID&#xff09;的方式处理数据。本文将通过详细的解释和实际示例&#xff0c;带你深入…...

VScode、Windsurf、Cursor 中 R 语言相关快捷键设置

前言 在生物信息学数据分析中&#xff0c;R语言是一个不可或缺的工具。为了提高R语言编程效率&#xff0c;合理设置快捷键显得尤为重要。本文介绍在VSCode Windsurf Cursor 中一些实用的R语言快捷键设置&#xff0c;让非 Rstudio 的 IDE 用起来得心应手&#x1f611; 操作种…...

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&#xff0c; Linux远程访问方式有telnet、ssh两种协议&#xff1b;有人可能还会说vnc和rdp协议方式&#xff0c;后面这两种主要是可视化桌面场景下的&#xff0c;并非主流。 时过境迁&#xff0c;telnet因安全性低逐渐被禁用淘汰&#xff0c;最后就…...

算法刷题Day16: BM41 输出二叉树的右视图

题目链接 描述 思路&#xff1a; 递归构造二叉树在Day15有讲到。复习一下&#xff0c;就是使用递归构建左右子树。将中序和前序一分为二。 接下来是找出每一层的最右边的节点&#xff0c;可以利用队列层次遍历。 利用队列长度记录当前层有多少个节点&#xff0c;每次从队列里…...

登录授权的实现: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&#xff0c;coco,voc标记的睡岗检测数据集&#xff0c;可识别在桌子上趴着睡&#xff0c;埋头睡觉&#xff0c;座椅上靠着睡&#xff0c;平躺着睡等多种睡姿的检测&#xff0c;6549张图片 数据集分割 6549总图像数 训练组91&#xff05; 5949图片 有效集9&#x…...

数据库表的CRUD

SQL语句&#xff08;Structured Query Language&#xff09;是用于与关系型数据库进行交互的语言。下面是几个常用的SQL语句&#xff1a; 创建表&#xff1a; CREATE TABLE table_name ( column1 datatype, column2 datatype, column3 datatype, ... ); 插入数据&#xff1a; …...

Proxy与Reflect

监听对象操作 在Object中&#xff0c;可以通过defineProperty中的get&#xff0c;set进行监听&#xff0c; Proxy基本使用 有两个参数&#xff0c;第一个是要代理的对象&#xff0c;第二个是捕获器&#xff0c;在不知道捕获器使用哪个之前可以先传个空对象。就会启用默认的捕获…...

大模型Agent面试通关秘籍!小白程序员必备,附收藏版学习资源

大模型Agent面试通关秘籍&#xff01;小白程序员必备&#xff0c;附收藏版学习资源 本文分享了作者在阿里巴巴大模型Agent应用算法岗面试中的真实经验&#xff0c;涵盖了从一面到三面的高频技术问题及答题思路&#xff0c;包括大模型Agent核心模块解析、微调与提示工程关系、Ag…...

Perplexity Nature检索实战手册:9类典型查询失败场景+对应Prompt工程模板(含IEEE/ACS/Nature交叉验证结果)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Perplexity Nature文章检索实战手册导论 Perplexity Nature 是面向科研人员与技术从业者设计的智能学术检索增强工具&#xff0c;它融合了语义理解、引用图谱分析与跨源文献聚合能力&#xff0c;专为高…...

从经典工程恶作剧看理论派与实践派的思维碰撞与团队协作

1. 项目概述&#xff1a;一场经典的工程恶作剧及其启示在任何一个技术团队里&#xff0c;总有一些故事会口口相传&#xff0c;成为团队文化的一部分。我今天想分享的这个故事&#xff0c;发生在上世纪80年代初&#xff0c;一个微电路设计小组里。它无关乎高深的技术突破&#x…...

终极网盘直链下载助手完整指南:免费解锁八大平台高速下载

终极网盘直链下载助手完整指南&#xff1a;免费解锁八大平台高速下载 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天…...

FPGA仿真库配置避坑指南:Xilinx 7系、Altera Cyclone V、Lattice ECP5在ModelSim 10.6d下的完整流程

FPGA仿真库配置避坑指南&#xff1a;Xilinx 7系、Altera Cyclone V、Lattice ECP5在ModelSim 10.6d下的完整流程 第一次在ModelSim 10.6d环境下配置FPGA仿真库时&#xff0c;我花了整整三天时间排查各种路径错误和权限问题。直到现在&#xff0c;我还清楚地记得那个深夜——当仿…...

这家头部智能家居品牌是如何让全渠道电商闭环运营落地?

在电商渠道愈发多元的当下&#xff0c;让很多企业陷入 “数据多却用不好” 的困境。这不是个别现象&#xff0c;而是绝大多数全渠道电商企业正在经历的“成长烦恼”。今天&#xff0c;我们用一个真实案例&#xff0c;带您看看如何用一套系统&#xff0c;彻底告别这些噩梦。这家…...

收藏!小白程序员必备:2026年AI大模型就业新机遇与学习路线指南

根据世界经济论坛报告&#xff0c;到2030年科技、数据、AI等领域将创造1.7亿工作机会&#xff0c;同时淘汰9200万个岗位。AI市场规模预计到2034年达36804.7亿美元&#xff0c;年复合增长率19.20%。中国AI人才需求将远超供应。文章介绍了AI运营/AIGC内容创作者、算法工程师、大模…...

如何快速找回压缩包密码:ArchivePasswordTestTool完整使用指南

如何快速找回压缩包密码&#xff1a;ArchivePasswordTestTool完整使用指南 【免费下载链接】ArchivePasswordTestTool 利用7zip测试压缩包的功能 对加密压缩包进行自动化测试密码 项目地址: https://gitcode.com/gh_mirrors/ar/ArchivePasswordTestTool 你是否曾经遇到过…...

数据中心机架内互连新范式:为何PCIe正取代以太网与InfiniBand?

1. 数据中心互连的十字路口&#xff1a;为什么是PCIe&#xff1f;在数据中心这个庞大而精密的数字世界里&#xff0c;服务器、存储和网络设备之间的“对话”效率&#xff0c;直接决定了整个系统的性能上限。过去十几年&#xff0c;我们习惯了用以太网&#xff08;Ethernet&…...

动物森友会岛屿设计终极指南:用Happy Island Designer轻松规划你的梦想岛屿

动物森友会岛屿设计终极指南&#xff1a;用Happy Island Designer轻松规划你的梦想岛屿 【免费下载链接】HappyIslandDesigner "Happy Island Designer (Alpha)"&#xff0c;是一个在线工具&#xff0c;它允许用户设计和定制自己的岛屿。这个工具是受游戏《动物森友会…...