设计模式——原型设计模式(创建型)
摘要
本文详细介绍了原型设计模式,这是一种创建型设计模式,通过复制现有对象(原型)来创建新对象,避免使用new关键字,可提高性能并简化对象创建逻辑。文章阐述了其优点,如提高性能、动态扩展和简化构造逻辑,以及缺点,如深拷贝实现复杂、复杂资源复制困难和易破坏封装性。还介绍了使用条件、结构、实现方式、适合场景和实战示例,并探讨了Spring中原型思想的应用。
1. 原型设计模式定义
原型设计模式是一种创建型设计模式,其核心思想是:通过复制现有的对象(原型)来创建新对象,而不是通过 new
关键字来实例化,从而提高性能并简化对象创建逻辑。使用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。
特性 | 说明 |
创建方式 | 使用已有对象(原型)复制创建,而不是 new |
拷贝类型 | 通常支持 浅拷贝 和 深拷贝 |
接口 | 通常实现 |
性能 | 适合对象创建代价高、结构复杂的场景 |
1.1. ✅ 原型模式的优点
- 提高性能:避免重复创建复杂对象。
- 动态扩展:在运行时动态创建对象。
- 简化构造逻辑:不用关心构造细节,只需拷贝。
1.2. ❌ 缺点
- 深拷贝实现复杂(需注意引用对象)
- 对象包含复杂资源(如数据库连接)时不易复制
- 克隆过程容易破坏封装性
1.3. 📌 原型设计模式使用条件
适合以下场景:
场景 | 说明 |
对象构造开销大 | 如数据库连接、网络通信等初始化代价高 |
对象构造逻辑复杂 | 包含多个参数、状态配置等 |
多个相似对象 | 只需要改变少部分属性 |
2. 原型设计模式结构
2.1. 原型设计模式类图
- 客户(Client)角色:客户类提出创建对象的请求。
- 抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。
- 具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口
2.2. 原型设计模式时序图
3. 原型设计模式实现方式
原型设计模式的实现方式核心在于 —— 通过克隆现有对象来创建新对象,而不是使用 new
。在 Java 中,通常通过实现 Cloneable
接口并重写 clone()
方法来完成。下面是常见的两种实现方式:浅拷贝和深拷贝。
3.1. 🛠️ 原型模式实现方式
实现方式 | 描述 |
浅拷贝 | 复制对象本身,但对象中的引用类型字段只复制地址(共享引用) |
深拷贝 | 复制对象及其引用对象(创建完全独立的新对象) |
3.2. ✅ 浅拷贝示例(实现 Cloneable)
@Data
public class Person implements Cloneable {private String name;private int age;@Overridepublic Person clone() {try {return (Person) super.clone(); // 浅拷贝} catch (CloneNotSupportedException e) {throw new RuntimeException(e);}}
}
✅ 浅拷贝适用于字段都是基本类型或不可变类型(如 String)。
3.3. ✅ 深拷贝示例(引用字段也复制)
@Data
public class Person implements Cloneable {private String name;private int age;private Address address; // 引用类型@Overridepublic Person clone() {try {Person cloned = (Person) super.clone();// 深拷贝 Address 对象cloned.address = address.clone();return cloned;} catch (CloneNotSupportedException e) {throw new RuntimeException(e);}}
}@Data
class Address implements Cloneable {private String city;@Overridepublic Address clone() {try {return (Address) super.clone();} catch (CloneNotSupportedException e) {throw new RuntimeException(e);}}
}
3.4. 🔁 使用序列化实现深拷贝(通用方案)
public static <T extends Serializable> T deepCopy(T obj) {try (ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos)) {oos.writeObject(obj);try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis)) {return (T) ois.readObject();}} catch (Exception e) {throw new RuntimeException("深拷贝失败", e);}
}
3.5. 📌 实现步骤总结
步骤 | 描述 |
1. 实现 | 否则调用 |
2. 重写 | 调用 |
3. 深拷贝时递归调用子对象的 | 保证对象间完全独立 |
3.6. 💡 Tips(在项目中使用时注意):
- 不要忘了处理 引用类型字段(深拷贝)
- 可以用工具类如 Apache Commons Lang 的
SerializationUtils.clone()
简化处理 - Java
record
类型天然不可变,结合原型模式更安全 - Spring 中
@Scope("prototype")
是原型思想的一种应用
4. 原型设计模式适合场景
原型设计模式(Prototype Pattern)适用于通过复制(克隆)现有对象来快速创建新对象的场景。以下是它适用和不适用的场景对比:
4.1. ✅ 适合使用原型模式的场景
场景 | 说明 |
对象创建成本高 | 构造函数复杂、耗时(如 I/O、数据库、复杂计算)时,通过克隆避免重复创建 |
对象初始化复杂 | 需要设置很多配置/参数,克隆一个已初始化好的对象更方便 |
需要大量相似对象 | 如游戏中怪物/兵种生成、工作流中节点复制、表单复制等 |
运行时动态创建对象 | 不依赖类名和构造函数,只要能访问 prototype 对象即可 |
避免工厂或 new 创建的耦合 | 提高系统灵活性,符合开闭原则 |
4.2. ❌ 不适合使用原型模式的场景
场景 | 原因 |
对象结构简单、创建成本低 | 使用 |
对象包含复杂的循环引用关系 | clone 实现困难,容易出错 |
频繁深拷贝,性能反而变差 | clone 比 new 还慢,得不偿失 |
对象包含外部不可复制资源 | 如线程、Socket、数据库连接等资源不能复制 |
需要严格控制对象创建流程 | 比如工厂方法模式更适合定制构造逻辑 |
4.3. 🧠 实际项目应用建议
建议 | 说明 |
复杂对象或批量对象创建场景优先考虑 | 如任务调度系统中复制任务模板 |
引用类型多的对象必须小心实现深拷贝 | 避免共享引用带来的副作用 |
尽量配合原型注册表(原型缓存池) | 管理所有 prototype 模板,集中创建 |
5. 原型设计模式实战示例
在 Spring 项目中,原型设计模式(Prototype Pattern)最典型的应用方式是使用 Spring 的 @Scope("prototype")
注解来声明一个 Bean 为原型模式,使得每次注入都会创建一个新实例。
5.1. ✅ 示例:批量生成任务模板对象(适合原型模式场景)
5.1.1. 定义一个任务对象(复杂初始化逻辑)
@Data
public class Task implements Cloneable {private String name;private String type;private List<String> steps = new ArrayList<>();public Task(String name, String type) {this.name = name;this.type = type;this.steps.add("初始化");this.steps.add("执行中");this.steps.add("结束");}@Overridepublic Task clone() {try {Task clone = (Task) super.clone();// 深拷贝clone.steps = new ArrayList<>(this.steps);return clone;} catch (CloneNotSupportedException e) {throw new RuntimeException(e);}}
}
5.1.2. Spring容器中定义该对象为原型 Bean
@Configuration
public class TaskConfig {@Bean@Scope("prototype") // 每次注入时都会创建新实例public Task taskPrototype() {return new Task("默认任务", "general");}
}
5.1.3. 任务服务中使用 Prototype Bean并进行克隆
@Service
public class TaskService {@Autowiredprivate ApplicationContext applicationContext;public Task createNewTask(String name, String type) {// 每次从容器获取都会是一个新实例(原型)Task prototype = applicationContext.getBean(Task.class);Task newTask = prototype.clone(); // 克隆一份再设置参数newTask.setName(name);newTask.setType(type);return newTask;}
}
5.1.4. ✅ 为什么这是原型模式适合的场景?
点 | 说明 |
创建成本高 | 每个任务初始化流程复杂,创建频繁 |
需要批量创建不同配置的对象 | 每个任务有不同参数,复用模板快速创建 |
运行时动态变化 | 原型对象提供灵活性,可随时根据当前需求构造 |
6. 原型设计模式思考
6.1. Spring 中 @Scope("prototype")
是原型思想的一种应用?
使用 @Scope("prototype")
标注的 Bean,每次从 Spring 容器中获取时,都会创建一个全新的实例,而不是复用同一个对象。这就是“原型”的核心思想。
Prototype 模式的定义:“用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。”(即:通过复制一个“原型对象”来生成新对象)
6.1.1. Spring 中如何实现这个思想?
Prototype 模式要素 | Spring 的对应机制 |
原型对象 | Bean 的定义(类 + 配置) |
拷贝新对象 | 每次调用 |
统一管理原型 | 由 Spring 容器负责构造、注入依赖等生命周期管理 |
6.1.2. 示例
@Component
@Scope("prototype")
public class Task {public Task() {System.out.println("新任务实例被创建");}
}
@Autowired
private ApplicationContext applicationContext;public void createTasks() {Task t1 = applicationContext.getBean(Task.class); // 创建一个新实例Task t2 = applicationContext.getBean(Task.class); // 再创建一个新实例System.out.println(t1 == t2); // false
}
6.1.3. prototype与singleton
的区别
特性 |
|
|
实例个数 | 全局一个 | 每次请求新建 |
生命周期管理 | Spring 管 | Spring 只负责创建,不管理销毁 |
适用场景 | 共享服务、无状态组件 | 有状态对象、频繁创建的临时对象 |
博文参考
- 创建型 - 原型模式(Prototype) | Java 全栈知识体系
- 原型设计模式
相关文章:

设计模式——原型设计模式(创建型)
摘要 本文详细介绍了原型设计模式,这是一种创建型设计模式,通过复制现有对象(原型)来创建新对象,避免使用new关键字,可提高性能并简化对象创建逻辑。文章阐述了其优点,如提高性能、动态扩展和简…...
react库:class-variance-authority
文章目录 前言一、cva 的核心作用二、代码逐层解析参数详解基础样式(第一个参数):variant:定义颜色/风格变体(如 default、destructive)。size:定义尺寸变体(如 sm、lg)。…...

通过mqtt 点灯
1 解析mqtt 传过来的json 用cjson 解析。 2 类似mvc的结构,调用具体的动作函数 定义设备处理结构体:使用结构体数组映射设备名称与处理函数,实现可扩展的指令分发分离设备逻辑:为每个设备(如 LED、Motor࿰…...
随笔笔记记录5.28
1.setOptMode -opt_leakage_to_dynamic_ratio 调整漏电与动态功耗的优化权重( 1.0 表示仅优化漏电)。 需指定-opt_power_effort(none | low | high),同时使用 2.set_ccopt_property max_source_to_sink_net_length …...

大数据-273 Spark MLib - 基础介绍 机器学习算法 决策树 分类原则 分类原理 基尼系数 熵
点一下关注吧!!!非常感谢!!持续更新!!! 大模型篇章已经开始! 目前已经更新到了第 22 篇:大语言模型 22 - MCP 自动操作 FigmaCursor 自动设计原型 Java篇开…...

基于 Spring Boot + Vue 的墙绘产品展示交易平台设计与实现【含源码+文档】
项目简介 本系统是一个基于 Spring Boot Vue 技术栈开发的墙绘产品展示交易平台,旨在提供一个高效、便捷的在线商城平台,方便用户浏览、选购墙绘产品,并提供管理员进行商品管理、订单管理等功能。系统采用了前后端分离的架构,前…...

【机器学习】支持向量机
文章目录 一、支持向量机简述1.概念2.基本概念3.算法介绍4.线性可分5.算法流程 二、实验1.代码介绍2.模型流程3.实验结果4.实验小结 一、支持向量机简述 1.概念 支持向量机(SVM)是一类按监督学习方式对数据进行二元分类的广义线性分类器,其…...

ONLYOFFICE深度解锁系列.4-OnlyOffice客户端原理-真的不支持多端同步
最近很多客户多要求直接部署onlyoffice服务端,还问能否和onlyoffice的客户端进行文件同步,当时真是一脸懵,还有的是老客户,已经安装了onlyoffice协作空间的,也在问如何配置客户端和协作空间的对接。由于问的人太多了,这里统一回复,先说结论,再说原理: 1.onlyoffice document s…...

LLMTIME: 不用微调!如何用大模型玩转时间序列预测?
今天是端午节,端午安康!值此传统佳节之际,我想和大家分享一篇关于基于大语言模型的时序预测算法——LLMTIME。随着人工智能技术的飞速发展,利用大型预训练语言模型(LLM)进行时间序列预测成为一个新兴且极具…...

2.从0开始搭建vue项目(node.js,vue3,Ts,ES6)
从“0到跑起来一个 Vue 项目”,重点是各个工具之间的关联关系、职责边界和技术演化脉络。 从你写代码 → 到代码能跑起来 → 再到代码可以部署上线,每一步都有不同的工具参与。 😺😺1. 安装 Node.js —— 万事的根基 Node.js 是…...
MySQL 高可用实现方案详解
MySQL 高可用实现方案详解 一、高可用核心概念 高可用性(High Availability)指系统能够持续提供服务的能力,通常用可用性=正常服务时间/(正常服务时间+故障时间)来衡量,99.99%可用性表示年故障时间不超过52.6分钟。 MySQL实现高可用需要解决以下几个关键问题: 故障自动检测…...

【pycharm】如何连接远程仓库进行版本管理(应用版本)
软件:Pycharm OS:Windows 一、Git基础设置 这里略过Git安装,需要可以参考:windows安装git(全网最详细,保姆教程)-CSDN博客 1. 配置Git 打开GitBash。分次输入下列命令。 git config --…...

linux 1.0.7
用户和权限的含义与作用 linux中的用户和文件 用户的权限是非常重要的 而且有些程序需要使用管理员身份去执行 这些都是非常重要的 不可能让所有的人拥有所有的权限 这样的工具可以避免非法的手段来修改计算机中的数据 linux之所以安全还是权限管理做的很棒 每个登录的用户都有…...
【Rust 轻松构建轻量级多端桌面应用】
使用 Tauri 框架构建跨平台应用 Tauri 是一个基于 Rust 的轻量级框架,可替代 Electron,用于构建高性能、低资源占用的桌面应用。其核心优势在于利用系统原生 WebView 而非捆绑 Chromium,显著减小应用体积。 安装 Tauri 需要先配置 Rust 环境…...

IEEE P370:用于高达 50 GHz 互连的夹具设计和数据质量公制标准
大多数高频仪器,如矢量网络分析仪 (VNA) 和时域反射仪 (TDR),都可以在同轴接口的末端进行非常好的测量。然而,复杂系统中使用的互连很少具有同轴接口。用于表征这些设备的夹具的设计和实施会对测…...
青少年编程与数学 02-020 C#程序设计基础 09课题、面向对象编程
青少年编程与数学 02-020 C#程序设计基础 09课题、面向对象编程 一、概述1. 对象(Object)2. 类(Class)3. 封装(Encapsulation)4. 继承(Inheritance)5. 多态(Polymorphism…...

Denoising Autoencoders 视频截图 DAEs简单实现 kaggle 去噪编码器
https://www.bilibili.com/video/BV1syzrYaEtw Denoising Autoencoders (DAEs) 是一种无监督学习模型,属于自动编码器(Autoencoder)的一种扩展形式。它们的目标是通过训练神经网络来学习数据的鲁棒表示(robust representation&a…...

GoogLeNet网络模型
GoogLeNet网络模型 诞生背景 在2014年的ImageNet图像识别挑战赛中,一个GoogLeNet的网络架构大放异彩,与VGG不同的是,VGG用的是3*3的卷积,而GoogLeNet从1*1到7*7的卷积核都用,也就是使用不同大小的卷积核组合。 网络…...
LeetCode Hot100 (贪心)
121. 买卖股票的最佳时机 题意 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。返回你可以从…...

仿真科普|弥合市场需求断层,高性能仿真,“性能”与“安全”如何兼得?
2025年3月,塔塔科技(Tata Technologies)确认曾在去年遭受勒索软件组织“猎手国际”(Hunters International)的攻击,1.4TB工程数据被窃取,涉及航空发动机热障涂层工艺参数等超过 73 万份文件。 X…...
工业控制核心引擎高性能MCU——MM32F5370
RAMSUN提供的MM32F5370搭载180MHz Arm China Star-MC1处理器,集成DSP、FPU与三角函数加速单元(CORDIC),轻松应对复杂算法需求。其技术亮点包括: 超高精度PWM:8通道208ps级高精度PWM输出,满足储能…...

Maven---配置本地仓库
目录 5. 5.1在Maven路径下新建文件夹用于本地仓库存储 5.2 复制本地仓库路径 5.3 找到配置文件路径,使用VSCode方式打开 5.4 新增一行代码 5.5 复制本地仓库路径,设置存储路径 5.1在Maven路径下新建文件夹用于本地仓库存储 5.2 复制本地仓库路径 5…...
vue中events选项与$on监听自定义事件他们的区别与不同,以及$emit与$on之间通信和mounted生命周期钩子函数有哪些作用和属性
events 选项确实曾经被用于监听事件,但它主要用于早期版本的 Vue.js(1.x)中,用于组件之间的通信。在 Vue 2.x 中,events 选项已经被废弃,取而代之的是更强大的 $emit 和 $on 方法。 使用$emit来监听自定义…...

【C++ 】智能指针:内存管理的 “自动导航仪”
目录 一、引入 二、智能指针的两大特性: 1、RAII 特点: 好处: 2、行为像指针 三、智能指针起初的缺陷:拷贝问题 四、几种智能指针的介绍。 1、C98出现的智能指针——auto_ptr auto_ptr解决上述拷贝构造的问题:…...

设备制造行业项目管理难点解析,如何有效解决?
在设备制造行业,项目管理是企业运营的核心环节,直接影响项目交付效率、成本控制和盈利能力。然而,由于行业特性复杂、项目周期长、涉及部门多,企业在实际操作中常常面临诸多管理痛点。金众诚工程项目管理系统,依托金蝶…...

浅谈 PAM-2 到 PAM-4 的信令技术演变
通信信令技术演进:从 PAM-2 到 PAM-4 在当今数字化高速发展的时代,数据传输需求呈爆炸式增长,行业对通信带宽的要求愈发严苛。为顺应这一趋势,通信信令技术不断革新,曾经占据主导地位的不归零(NRZÿ…...

Protos-SIP:经典 SIP 协议模糊测试工具!全参数详细教程!Kali Linux教程!
简介 该测试套件的目的是评估会话发起协议 (SIP) 实现的实现级别安全性和稳健性。 Protos-SIP 是一款专为 SIP 协议模糊测试(Fuzzing)设计的工具,最初由 OUSPG(Oulu University Secure Programming Group)开发&#…...

复数三角不等式简介及 MATLAB 演示
复数三角不等式简介及 MATLAB 演示 1. 复数三角不等式简介 复数三角不等式(Complex Triangle Inequality)是复数的一种重要性质,它类似于普通的三角不等式,但适用于复数空间。具体来说,复数三角不等式可以描述复数之…...

【Doris基础】Apache Doris 基本架构深度解析:从存储到查询的完整技术演进
目录 1 引言 2 Doris 架构全景图 2 核心组件技术解析 2.1 Frontend 层(FE) 2.2 Backend 层(BE) 3 数据存储与复制机制 3.1 存储架构演进 3.2 副本复制策略 4 查询处理全流程解析 4.1 查询生命周期 5 高可用设计 5.1 F…...

程序人生-hellohelloo
计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 计算机与电子通信 学 号 2023111976 班 级 23L0504 学 生 孙恩旗 指 导 教 师 刘宏伟 计算机科…...