探索设计模式:原型模式
设计模式之原型模式
- 🧐1. 概念
- 🎯2. 原型模式的作用
- 📦3. 实现
- 1. 定义原型接口
- 2. 定义具体的原型类
- 3. 定义客户端
- 4. 结果
- 📰 4. 应用场景
- 🔍5. 深拷贝和浅拷贝

在面向对象编程中,设计模式是一种通用的解决方案,用于解决软件设计过程中常见的问题。原型模式(Prototype Pattern)作为创建型设计模式的一员,旨在通过复制现有对象来创建新对象,而非通过常规的构造函数。这种模式不仅简化了对象的创建过程,而且在特定情况下还能显著提升性能。
🧐1. 概念
原型模式允许客户端复制一个已存在的对象,而不是通过常规的构造器创建一个新的实例。这种方法的主要优点在于,如果对象的创建成本很高(例如,初始化过程复杂、需要从数据库加载大量数据等),那么通过复制现有对象的方式可以有效减少资源消耗,提高系统的整体性能。

Prototype(抽象原型类):它是声明克隆方法的接口,是所有具体原型类的公共父类,可以是抽象类也可以是接口,甚至还可以是具体实现类。ConcretePrototype(具体原型类):它实现在抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象。Client(客户端类):通过调用clone()方法来创建新的对象,并展示了原始对象与克隆对象之间的独立性。
🎯2. 原型模式的作用
- 简化对象创建:通过复制现有的对象,可以避免复杂的构造过程,尤其是当对象的初始化需要进行大量的计算或资源分配时。
- 提高性能:对于那些创建成本高得对象,使用原型模式可以显著减少内存消耗和处理时间。
- 增加系统灵活性:通过修改原型对象得属性,可以快速生成不同状态的新对象,这比通过继承来实现更加灵活。
📦3. 实现
实现原型模式的核心在于定义一个原型接口,该接口包含一个用于复制自身的克隆方法。在不同的编程语言中,实现方式可能会有所不同,但基本思路是一致的。
1. 定义原型接口
public interface Prototype extends Cloneable {Prototype clone();
}
此处的
Cloneable接口是一个标记接口,表示该类可以被克隆。
类似的标记接口还有
Serializable:用于标记一个类的对象可以被序列化和反序列化。RandomAccess:用于标记一个列表支持随机访问,即通过索引直接访问元素吗,而不是遍历。Remote:用于远程方法调用,标记一个类支持远程方法调用。
2. 定义具体的原型类
public class ConcretePrototype implements Prototype {private String attribute;public ConcretePrototype(String attribute) {this.attribute = attribute;}@Overridepublic Prototype clone() {try {return (ConcretePrototype) super.clone();} catch (CloneNotSupportedException e) {throw new AssertionError("Cannot clone.", e);}}public String getAttribute() {return attribute;}public void setAttribute(String attribute) {this.attribute = attribute;}}
3. 定义客户端
public class Client {public static void main(String[] args) {ConcretePrototype prototype = new ConcretePrototype("Initial Value");ConcretePrototype clonedPrototype = (ConcretePrototype) prototype.clone();System.out.println("Original Attribute: " + prototype.getAttribute());System.out.println("Cloned Attribute: " + clonedPrototype.getAttribute());clonedPrototype.setAttribute("Modified Value");System.out.println("After Modification:");System.out.println("Original Attribute: " + prototype.getAttribute());System.out.println("Cloned Attribute: " + clonedPrototype.getAttribute());}
}
4. 结果

在这个示例中,ConcretePrototype 类实现了 Prototype 接口,并提供了具体的 clone() 方法实现。客户端代码展示了如何通过调用 clone() 方法来创建新的对象,并展示了原始对象与克隆对象之间的独立性。
📰 4. 应用场景

- 对象创建成本高:当对象的创建对象过程非常复杂或耗时,例如需要从网络加载数据、执行复炸的算法等,使用原型模式可以通过复制现有对象来节省时间和资源。
- 避免复杂的构造过程:如果对象的创建涉及到复杂的初始化步骤,使用原型模式可以简化这些步骤,通过复制已有对象来快速生成新的对象。
- 动态对象创建:在某些情况下,程序需要根据用户的输入或其他条件动态地创建对象。原型模式提供了一种灵活的方式来满足这种需求,无需预先定义所有的对象类型。
- 实际项目当中使用原型模式,实现
Cloneable接口并重写clone()方法。或者编写自己的特有的原型类Prototype,然后实现Prototype的clone()方法。
🔍5. 深拷贝和浅拷贝
在讨论原型模式时,深拷贝和浅拷贝是一个不可忽视的话题。浅拷贝只会复制对象的基本数据类型和其他对象的引用,而不会递归地复制引用对象本身。相反,深拷贝会递归地复制整个对象树,确保新对象与原有对象完全独立。
在 Java 中, 默认的 clone() 方法实现的是浅拷贝。如果需要实现深拷贝,通常需要手动编写代码来处理对象中的引用类型属性。例如,可以使用序列化和反序列化的方式来实现深拷贝:
public class DeepClonePrototype implements Cloneable, Serializable {private transient String attribute; // 使用 transient 修饰符表示不参与序列化public DeepClonePrototype(String attribute) {this.attribute = attribute;}public String getAttribute() {return this.attribute;}public void setAttribute(String attribute) {this.attribute = attribute;}@Overrideprotected DeepClonePrototype clone() {try {// 使用序列化和反序列化实现深拷贝ByteArrayOutputStream byteOut = new ByteArrayOutputStream();ObjectOutputStream out = new ObjectOutputStream(byteOut);out.writeObject(this);ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());ObjectInputStream in = new ObjectInputStream(byteIn);return (DeepClonePrototype) in.readObject();} catch (IOException | ClassNotFoundException e) {throw new AssertionError("Cannot clone.", e);}}}
相关文章:
探索设计模式:原型模式
设计模式之原型模式 🧐1. 概念🎯2. 原型模式的作用📦3. 实现1. 定义原型接口2. 定义具体的原型类3. 定义客户端4. 结果 📰 4. 应用场景🔍5. 深拷贝和浅拷贝 在面向对象编程中,设计模式是一种通用的解决方案…...
NLP论文速读(EMNLP 2023)|工具增强的思维链推理
论文速读|ChatCoT: Tool-Augmented Chain-of-Thought Reasoning on Chat-based Large Language Models 论文信息: 简介: 本文背景是关于大型语言模型(LLMs)在复杂推理任务中的表现。尽管LLMs在多种评估基准测试中取得了优异的成绩…...
JVM垃圾回收详解.②
空间分配担保 空间分配担保是为了确保在 Minor GC 之前老年代本身还有容纳新生代所有对象的剩余空间。 《深入理解 Java 虚拟机》第三章对于空间分配担保的描述如下: JDK 6 Update 24 之前,在发生 Minor GC 之前,虚拟机必须先检查老年代最大…...
什么是事务,事务有什么特性?
事务的四大特性(ACID) 原子性(Atomicity) 解释:原子性确保事务中的所有操作要么全部完成,要么全部不做。这意味着事务是一个不可分割的工作单元。在数据库中,这通常通过将事务的操作序列作为一个…...
深入解析:如何使用 PyTorch 的 SummaryWriter 进行深度学习训练数据的详细记录与可视化
深入解析:如何使用 PyTorch 的 SummaryWriter 进行深度学习训练数据的详细记录与可视化 为了更全面和详细地解释如何使用 PyTorch 的 SummaryWriter 进行模型训练数据的记录和可视化,我们可以从以下几个方面深入探讨: 初始化 SummaryWriter…...
企业微信中设置回调接口url以及验证 spring boot项目实现
官方文档: 接收消息与事件: 加密解密文档:加解密库下载与返回码 - 文档 - 企业微信开发者中心 下载java样例 加解密库下载与返回码 - 文档 - 企业微信开发者中心 将解压开的代码 ‘将文件夹:qq\weixin\mp\aes的代码作为工具拷…...
电脑超频是什么意思?超频的好处和坏处
嗨,亲爱的小伙伴!你是否曾经听说过电脑超频?在电脑爱好者的圈子里,这个词似乎非常熟悉,但对很多普通用户来说,它可能还是一个神秘而陌生的存在。 今天,我将带你揭开超频的神秘面纱,…...
在 AMD GPU 上构建深度学习推荐模型
Deep Learning Recommendation Models on AMD GPUs — ROCm Blogs 2024 年 6 月 28 日 发布者 Phillip Dang 在这篇博客中,我们将演示如何在支持 ROCm 的 AMD GPU 上使用 PyTorch 构建一个简单的深度学习推荐模型 (DLRM)。 简介 DLRM 位于推荐系统和深度学习的交汇…...
阿里云IIS虚拟主机部署ssl证书
宝塔配置SSL证书用起来是很方便的,只需要在站点里就可以配置好,但是云虚拟主机在管理的时候是没有这个权限的,只提供了简单的域名管理等信息。 此处记录下阿里云(原万网)的IIS虚拟主机如何配置部署SSL证书。 进入虚拟…...
Python运算符列表
运算符 描述 xy,x—y 加、减,“"号可重载为连接符 x*y,x**y,x/y,x%y 相乘、求平方、相除、求余,“*”号可重载为重复,“%"号可重载为格式化 <,<,&…...
MFC图形函数学习09——画多边形函数
这里所说的多边形是指在同一平面中由多条边构成的封闭图形,强调封闭二字,否则无法进行颜色填充,多边形包括凸多边形和凹多边形。 一、绘制多边形函数 原型:BOOL Polygon(LPPOINT lpPoints,int nCount); 参数&#x…...
GaussianDreamer: Fast Generation from Text to 3D Gaussians——点云论文阅读(11)
此内容是论文总结,重点看思路!! 文章概述 本文提出了一种快速从文本生成3D资产的新方法,通过结合3D高斯点表示、3D扩散模型和2D扩散模型的优势,实现了高效生成。该方法利用3D扩散模型生成初始几何,通过噪声…...
k8s篇之控制器类型以及各自的适用场景
1. k8s中控制器介绍 在 Kubernetes 中,控制器(Controller)是集群中用于管理资源的关键组件。 它们的核心作用是确保集群中的资源状态符合用户的期望,并在需要时自动进行调整。 Kubernetes 提供了多种不同类型的控制器,每种控制器都有其独特的功能和应用场景。 2. 常见的…...
Node.js 笔记(一):express路由
代码 建立app.js文件,代码如下: const express require(express) const app express() const port 3002app.get(/,(req,res)>{res.send(hello world!)})app.listen(port,()>{console.log(sever is running on http://localhost:${port}) })问…...
bash笔记
0 $0 是脚本的名称,$# 是传入的参数数量,$1 是第一个参数,$BOOK_ID 是变量BOOK_ID的内容 1 -echo用于在命令窗口输出信息 -$():是命令替换的语法。$(...) 会执行括号内的命令,并将其输出捕获为一个字符串ÿ…...
mongoDB副本集搭建-docker
MongoDB副本集搭建-docker 注:在进行副本集搭建前,请先将服务部署docker环境并正常运行。 #通过--platform指定下载镜像的系统架构 在这我用的是mongo:4.0.28版本 arm64系统架构的mongo镜像 docker pull --platformlinux/arm64 mongo:4.0.2#查看镜像是…...
Python软体中使用 Flask 或 FastAPI 搭建简单 RESTful API 服务并实现限流功能
Python软体中使用 Flask 或 FastAPI 搭建简单 RESTful API 服务并实现限流功能 引言 在现代 web 开发中,RESTful API 已成为应用程序之间进行通信的标准方式。Python 提供了多种框架来帮助开发者快速搭建 RESTful API 服务,其中 Flask 和 FastAPI 是最受欢迎的两个框架。本…...
CentOS操作系统下安装Nacos
CentOS下安装Nacos 前言 这在Centos下安装配置Nacos 下载Linux版Nacos 首先到Nacos的 Github页面,找到所需要安装的版本 也可以右键复制到链接,然后通过wget命令进行下载 wget https://github.com/alibaba/nacos/releases/download/1.3.2/nacos-ser…...
C++设计模式之适配器模式与桥接模式,装饰器模式及代理模式相似点与不同点
适配器模式、桥接模式、装饰器模式和代理模式在形式上有一些相似之处,因为它们都涉及到对类的功能或接口的修改、增强或转换。然而,它们在动机和目的上有着显著的不同。以下是对这些模式相似点和不同点的清晰说明: 相似点: 结构…...
ThreadLocal 和 Caffeine 缓存是两种不同的缓存机制,它们在用途和实现上有明显的区别
ThreadLocal 和 Caffeine 缓存是两种不同的缓存机制,它们在用途和实现上有明显的区别: ThreadLocal 缓存: ThreadLocal 提供了线程局部变量的功能,每个线程可以访问自己的局部变量,而不会与其他线程冲突。ThreadLocal …...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
