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

Java创造型模式之原型模式详解

设计模式是面向对象设计中的一种标准方法,用于解决常见的设计问题。原型设计模式(Prototype Pattern)是23种经典设计模式之一,属于创建型模式,它允许通过复制现有对象来创建新对象,而不是通过构造函数或工厂方法来创建。这样,开发者可以在运行时通过复制原型对象来快速生成新的对象,极大地提高了程序的灵活性和性能。

本文将深入讲解Java中的原型设计模式,解释其概念、使用场景、以及如何在Java中实现。

一、原型设计模式的定义

原型模式是一种通过复制原型对象来创建新对象的设计模式。它使得对象的创建不依赖于具体的类构造,而是依赖于原型实例。原型实例通过浅拷贝或深拷贝的方式复制,从而生成新的实例对象。

关键点:

  1. 原型对象:一个可以复制的对象。
  2. 克隆操作:通过复制(克隆)原型对象来创建新的对象。
  3. 浅拷贝与深拷贝:浅拷贝指的是复制对象时,原对象和复制对象共享引用类型的成员变量。深拷贝则是完全复制对象,确保复制对象和原对象没有任何共享的引用类型变量。

二、使用原型模式的原因

在某些场景中,传统的对象创建方式可能过于复杂或不够高效。通过原型模式,我们可以通过现有的对象(即原型)来快速创建新对象,而无需重新构造对象。

原型模式的优势:

  1. 提高性能:当对象的创建过程比较复杂时,通过原型复制对象来创建新实例通常比使用构造函数更高效。
  2. 简化创建过程:对象的创建不需要重复复杂的初始化操作,只需要通过复制已有对象来实现。
  3. 支持变更:通过复制原型对象,开发者可以在运行时修改对象的某些属性,而不影响原对象。

适用场景:

  • 创建对象的过程较为复杂,且有多个相似对象需要频繁创建时,原型模式尤其有效。
  • 需要在程序运行时动态创建大量相似对象的情况。
  • 在复制对象时不希望重复调用构造函数,特别是当对象初始化代价较大时。

三、原型模式的实现

在Java中,原型模式通常通过实现Cloneable接口来实现,Cloneable接口是Java标准库中的一个标记接口,表示该对象支持克隆操作。Object类中的clone()方法是用于执行浅拷贝的默认实现。

1. 浅拷贝与深拷贝

  • 浅拷贝:复制对象时,只复制对象本身的基本数据类型成员,引用类型成员复制的是地址,意味着原对象和克隆对象会共享引用类型的成员。
  • 深拷贝:复制对象时,不仅复制对象本身,还会复制对象的引用类型成员,确保原对象和克隆对象互不影响。

2. 实现原型模式的步骤

步骤 1:实现 Cloneable 接口

首先,确保要复制的类实现了 Cloneable 接口。Cloneable接口是一个标记接口,它告诉Object.clone()方法该对象支持克隆操作。

步骤 2:重写 clone() 方法

由于Object类的clone()方法是保护的(protected),我们需要在自己的类中覆盖clone()方法。通常我们会将clone()方法设为public,以便外部可以调用。

步骤 3:深拷贝或浅拷贝

根据需求,可以在clone()方法中实现深拷贝或浅拷贝。默认的clone()方法是浅拷贝,如果需要深拷贝,需要手动实现。

四、Java中原型设计模式的示例代码

1、浅拷贝

// 实现Cloneable接口
class Prototype implements Cloneable {private String name;private int age;// 构造方法public Prototype(String name, int age) {this.name = name;this.age = age;}// 获取对象的浅拷贝@Overridepublic Prototype clone() {try {return (Prototype) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;}// Getter和Setter方法public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Prototype{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class PrototypeDemo {public static void main(String[] args) {// 创建原型对象Prototype original = new Prototype("Alice", 30);System.out.println("Original Object: " + original);// 克隆原型对象Prototype clone = original.clone();System.out.println("Cloned Object: " + clone);// 修改克隆对象的属性clone.setName("Bob");clone.setAge(25);System.out.println("Modified Cloned Object: " + clone);System.out.println("Original Object after modification: " + original);}
}

结果为: 

Original Object: Prototype{name='Alice', age=30}
Cloned Object: Prototype{name='Alice', age=30}
Modified Cloned Object: Prototype{name='Bob', age=25}
Original Object after modification: Prototype{name='Alice', age=30}

2、深拷贝

class Address {private String street;private String city;public Address(String street, String city) {this.street = street;this.city = city;}public Address(Address address) {this.street = address.street;this.city = address.city;}@Overridepublic String toString() {return "Address{" +"street='" + street + '\'' +", city='" + city + '\'' +'}';}
}class DeepPrototype implements Cloneable {private String name;private Address address;public DeepPrototype(String name, Address address) {this.name = name;this.address = address;}@Overridepublic DeepPrototype clone() {try {DeepPrototype cloned = (DeepPrototype) super.clone();cloned.address = new Address(this.address); // 深拷贝return cloned;} catch (CloneNotSupportedException e) {e.printStackTrace();}return null;}@Overridepublic String toString() {return "DeepPrototype{" +"name='" + name + '\'' +", address=" + address +'}';}
}public class DeepPrototypeDemo {public static void main(String[] args) {Address address = new Address("Baker Street", "London");DeepPrototype original = new DeepPrototype("John", address);System.out.println("Original Object: " + original);// 深拷贝原型对象DeepPrototype cloned = original.clone();System.out.println("Cloned Object: " + cloned);// 修改克隆对象的属性cloned.address = new Address("Wall Street", "New York");System.out.println("Modified Cloned Object: " + cloned);System.out.println("Original Object after modification: " + original);}
}

结果为:

Original Object: DeepPrototype{name='John', address=Address{street='Baker Street', city='London'}}
Cloned Object: DeepPrototype{name='John', address=Address{street='Baker Street', city='London'}}
Modified Cloned Object: DeepPrototype{name='John', address=Address{street='Wall Street', city='New York'}}
Original Object after modification: DeepPrototype{name='John', address=Address{street='Baker Street', city='London'}}

五、总结

原型设计模式通过克隆现有对象来创建新对象,而不是每次都通过构造函数创建。这种方式非常适合需要频繁创建相似对象的场景。Java提供了Cloneable接口和clone()方法来支持该模式的实现。在实际开发中,使用原型模式可以减少对象创建时的性能开销,同时也可以在对象状态变化时避免重复操作。

无论是浅拷贝还是深拷贝,原型模式都能有效提高开发效率,并在某些情况下避免不必要的资源浪费。理解并合理使用原型模式,可以在复杂系统的设计中发挥重要作用。

相关文章:

Java创造型模式之原型模式详解

设计模式是面向对象设计中的一种标准方法,用于解决常见的设计问题。原型设计模式(Prototype Pattern)是23种经典设计模式之一,属于创建型模式,它允许通过复制现有对象来创建新对象,而不是通过构造函数或工厂…...

3.17日Man2Marine

上游任务 vs. 下游任务 任务类型作用你的研究中的例子上游任务(Upstream Task)训练通用的音频表示,提供特征在大规模人类语音数据集上进行自监督学习下游任务(Downstream Task)利用上游任务学到的特征进行具体任务微调模型进行海洋哺乳动物叫声分类在 NLP(自然语言处理)…...

Fisher信息、梯度方差与学习率调度器的计算流程

Fisher信息、梯度方差与学习率调度器的计算流程 目录 Fisher信息、梯度方差与学习率调度器的计算流程**步骤1:定义模型与数据集****步骤2:计算梯度与Fisher信息****步骤3:计算梯度方差****步骤4:定义学习率调度器****步骤5:参数更新流程****示例输出****关键概念说明**步骤…...

209、不大于n的数的组合(python)

题目 已知一个数n和可组合的数字集合s,通过组合数字集合构成一个数x,使其不大于n。 例如: n 22356789 a [2, 3, 4, 8, 9] x 22349999 代码实现 n 22356789 a [2, 3, 4, 8, 9] a.sort() s str(n) tag True res [] for i in range…...

Matlab 汽车电子驻车系统仿真分析

1、内容简介 Matlab 176-汽车电子驻车系统仿真分析 可以交流、咨询、答疑 2、内容说明 略 摘 要: 论述了电子驻车制动控制系统的基本结构 、 组成及功能,并基于 Matlab/Simulink ,构建了包括直流电机 、 丝杠螺母及其内部 零件和相关摩擦力…...

蓝桥杯备考----模拟算法 phone number

嗯。这道题可以在两个和三个数字加-,我们只要随便输出一个奏行 那么!我们规范一下,我们尽可能的只在两个数字之间加,但是如果一共奇数个的话,我们就让最后三个成一组,也就是说,我们用的是个小贪…...

Unity WebGL IIS报错无法使用

Unity WebGL IIS报错无法使用 原因1:WebGL文件夹无访问权限 右键WebGL文件夹-属性 点击安全-编辑-添加 输入ever点击确定-应用即可...

【算法学习之路】11.并查集

并查集 前言一.简介二.基础并查集三.基础并查集题目12 四.种类并查集(扩展域并查集)五.种类并查集的题目 前言 我会将一些常用的算法以及对应的题单给写完,形成一套完整的算法体系,以及大量的各个难度的题目,目前算法也…...

第三课:Python递归编程艺术(从基础到优化)

递归,作为编程中一种优雅而强大的技术,以其简洁的代码风格和强大的问题解决能力,在算法设计中占据着举足轻重的地位。然而,递归的奥秘不仅仅在于其表面的简洁,更在于其背后的逻辑深度与优化技巧。本文将深入探讨递归编…...

插入排序程序并行化

一 插入排序 插入排序是稳定的原地排序算法,核心思想是逐步构建有序序列。对于未排序部分的每个元素,在已排序序列中从后向前扫描,找到合适位置插入。 二 并行化思路 1 分块排序 将数组分成多个子块,每个线程使用插入排序处理一块。 2 归并合并 将各有序子块归并成最终数…...

【系统架构设计师】操作系统 - 文件管理 ③ ( 树形目录结构 | 文件属性 | 绝对路径 与 相对路径 )

文章目录 一、树形目录结构1、树形目录结构 概念简介2、树形目录结构 组成3、文件属性4、树形目录结构 示例 二、绝对路径 与 相对路径1、绝对路径2、相对路径3、绝对路径 与 相对路径 对比 一、树形目录结构 1、树形目录结构 概念简介 " 树形目录结构 “ 又称为 ” 多级目…...

【量化科普】Standard Deviation,标准差

【量化科普】Standard Deviation,标准差 🚀量化软件开通 🚀量化实战教程 在量化投资领域,标准差(Standard Deviation)是一个非常重要的统计指标,用于衡量一组数据的离散程度。简单来说&#…...

实验三 Python 数据可视化 Python 聚类-K-means(CQUPT)

一、实验目的 Python 数据可视化: 1、学习使用 jieba、wordcloud 等类库生成词云图。 2、学习使用 Matplotlib 库进行数据可视化。 Python 聚类-K-means: 1、理解聚类非监督学习方法的基本原理。 2、掌握 Python、numpy、pandas、sklearn 实现聚类…...

东方通TongHttpServer:企业级服务代理中间件的卓越之选

随着信息技术的飞速发展,企业对于高性能、高安全性的中间件需求日益增长。东方通作为中国中间件领域的领军企业,凭借其在“安全”、“数据”和“智慧”三大产品体系上的深厚积累,推出了TongHttpServer(简称THS)&#x…...

EB-Cable许可证的常见问题及解决方案

在使用EB-Cable软件时,许可证问题可能是用户经常遇到的挑战之一。为了帮助用户更好地理解和解决许可证相关的问题,本文将列举一些常见的EB-Cable许可证问题,并提供相应的解决方案。 常见问题一:许可证激活失败 问题描述&#xff…...

ZED X系列双目3D相机的耐用性与创新设计解析

在工业自动化和学术研究领域,高精度的视觉设备正成为提升效率和质量的关键。ZED X系列AI立体相机,凭借其先进的技术和耐用的设计,为这一领域带来了新的可能。 核心技术:深度感知与精准追踪 ZED X系列的核心技术之一是Neural Dept…...

深入解析Java面向对象三大特征之多态、final、抽象类与接口

面向对象编程(OOP)的三大核心特征为封装、继承、多态,其中多态是最具灵活性和扩展性的特性。本文将从多态的本质出发,结合final关键字、抽象类与接口的设计,深入探讨这些概念的应用场景及其在代码中的实现细节&#xf…...

jmeter 循环控制器遍历列表中的数据

jmeter遍历列表中的数据并使用if控制器做相应的处理 测试场景请求获取列表接口发送请求JSON Extractor 提取对应字段 Loop Controller计数器If Controller 测试场景 请求获取列表接口使用循环控制器遍历接口,根据state字段判断是否发起其他请求 请求获取列表接口 …...

【Linux内核系列】:进程板块与文件板块的综合

🔥 本文专栏:Linux 🌸作者主页:努力努力再努力wz 💪 今日博客励志语录: 人生中成功只是一时的,失败却是人生的主旋律,但是如何面对失败却把人分成了不同的样子,有的人会被…...

深入理解嵌入式开发中的三个重要工具:零长度数组、container_of 和 typeof

在嵌入式开发中,内核开发者经常需要处理复杂的数据结构和动态内存分配。零长度数组、container_of 宏和 typeof 是内核开发中三个非常重要的工具,它们在结构体管理、内存操作和类型处理中发挥着关键作用。本文将详细探讨这三个工具的功能、应用场景及其在内核开发中的重要性。…...

第27周JavaSpringboot git初识

Git 课程笔记 一、Git 的介绍 1. Git 的诞生背景 Git 是 Linux 内核的作者 Linus Torvalds 为了更好地管理 Linux 内核开发而创建的版本控制系统。在 Linux 内核开发初期,由于开发者众多,协作成本很高,后来使用了 BitKeeper 工具来辅助协作…...

实战2. 利用Pytorch解决 CIFAR 数据集中的图像分类为 10 类的问题——提高精度

实战2. 利用Pytorch解决 CIFAR 数据集中的图像分类为 10 类的问题——提高精度 前期准备加载数据建立模型模型训练质量指标 让我们回到图像分类问题 CIFAR。 你的主要任务:实现整个模型训练流程,并在测试样本上获得良好的准确度指标值。 任务积分&#…...

CentOS高性能数据处理优化指南

在CentOS系统中,为实现高性能数据处理,需要从多个层面进行优化,包括系统配置、内核参数、硬件资源管理及软件优化等。 一、硬件优化 选择合适硬件是优化性能的基础,大规模数据处理任务建议使用多核CPU、大容量内存、SSD存储以及…...

深度剖析:Pytest Fixtures如何重塑自动化测试的可读性与高效性

关注开源优测不迷路 大数据测试过程、策略及挑战 测试框架原理,构建成功的基石 在自动化测试工作之前,你应该知道的10条建议 在自动化测试中,重要的不是工具 在编写单元测试时,是否发现自己写了很多相同/相似代码呢? 像…...

AIP-181 稳定级别

编号181原文链接AIP-181: Stability levels状态批准创建日期2019-02-18更新日期2019-02-18 虽然不同组织(谷歌或其他组织)拥有不同的产品生命周期,AIP使用以下术语指代API组件 稳定性 。 注意 这些稳定级别大致对应于Google Cloud中的产品发…...

比较 (leetcode 452. 用最少数量的箭引爆气球 leetcode 435. 无重叠区间 leetcode 56. 合并区间

leetcode系列 文章目录 一、射箭引爆气球二、无重叠区间三、合并区间总结 提示:小白个人理解,如有错误敬请谅解! 对于此类题目,都先按左区间排序,之后根据重叠还是不重叠来进行操作 一、射箭引爆气球 找到最大的重叠…...

什么是有限元力学?分而治之,将复杂问题转化为可计算的数学模型

有限元力学是应用有限元方法(Finite Element Method, FEM)解决力学问题的学科,属于计算力学的重要分支。它通过将复杂的连续体结构离散化为有限个简单单元的组合,结合数学和物理原理,近似求解力学行为(如应…...

python项目一键加密,极度简洁

在要加密的项目内运行python -m pip install py2safe 安装后cd到项目的根目录,运行py2safe 它会递归加密所有文件夹,不需要参数,拿过来就用,基于pyarmor开发,基本破解不了,太方便辣 这是readme文件,不仅提到了用法,还贴心的加入了口腔溃疡的治疗办法,真是太贴心了 # py2saf…...

STM32 ADC原理与驱动详解:从存储器映射到多通道采集(下) | 零基础入门STM32第六十六步

主题内容教学目的/扩展视频ADC读电位器和光敏重点课程电路原理,跳线设置,ADC功能分析,驱动程序,读出AD数据,读内部温度传感器数据。会设置参数,能读出AD值即可。 师从洋桃电子,杜洋老师 本文深入…...

JxBrowser 8.5.0 版本发布啦!

• 为 Compose Desktop 提供了硬件加速渲染支持 • 支持自定义 Chromium 二进制文件的品牌标识 • 多项质量改进 了解更多 获取 30 天免费试用...

LIN接口

LIN接口 前言LIN接口简介帧格式同步间隔段 (Break Field)同步段 (Sync Byte Field)受保护ID段 (Protected Identifier Field)数据段 (Data Field)校验和段 (Checksum Field) 帧在总线上的传输波形帧类型无条件帧事件触发帧偶发帧诊断帧保留帧 错误类型 IP 设计结构框图接口设计…...

【蓝桥杯每日一题】3.16

🏝️专栏: 【蓝桥杯备篇】 🌅主页: f狐o狸x 目录 3.9 高精度算法 一、高精度加法 题目链接: 题目描述: 解题思路: 解题代码: 二、高精度减法 题目链接: 题目描述&…...

prometheus-helm的使用

1、部署Prometheus监控平台 1、下载安装Prometheus (当前集群版本1.26.3) git clone https://github.com/prometheus-operator/kube-prometheus.git -b release-0.12 安装: cd kube-prometheus/ 创建命名空间和crd: kubectl …...

时间序列分析的军火库:AutoTS、Darts、Kats、PaddleTS、tfts 和 FancyTS解析

引言:时间序列分析的现代挑战 时间序列分析在多个领域中扮演着关键角色,包括工程、金融、气象、工业预测等。随着开源工具的快速发展,开发者可以通过多种库快速实现时间序列预测与分析。本文将对 AutoTS、Darts、Kats、PaddleTS、tfts 和 FancyTS 六大主流库进行详细解析,…...

TLSR8355F128芯片特色解析

TLSR8355F128 是泰凌微推出的一款高性能、低功耗的无线物联网芯片,具有以下特色: 丰富的协议支持:支持 2.4GHz 私有协议。这使得该芯片能够广泛应用于各种特殊的物联网场景,实现不同设备之间的互联互通。强大的处理能力&#xff…...

基于分类算法的学习失败预警(上)

文章目录 前言1.数据预处理1.1数据探索1.2数值化处理1.3空值填充1.4添加标签1.5特征筛选1.6数据集类别平衡1.7划分数据集1.8训练集类平衡1.9标准化 2.模型选择2.1建立模型2.2模型调参2.2.1遍历调参2.2.2网格搜索 结语 前言 本次案例通过对现有数据分析,采用如下图所…...

首页性能优化

首页性能提升是前端优化中的核心任务之一,因为首页是用户访问的第一入口,其加载速度和交互体验直接影响用户的留存率和转化率。 1. 性能瓶颈分析 在优化之前,首先需要通过工具分析首页的性能瓶颈。常用的工具包括: Chrome DevTo…...

整形在内存中的存储(例题逐个解析)

目录 一.相关知识点 1.截断: 2.整形提升: 3.如何 截断,整型提升? (1)负数 (2)正数 (3)无符号整型,高位补0 注意:提升后得到的…...

python中多重继承和泛型 作为模板让子类实现具体业务逻辑

示例代码: T TypeVar("T", bound"NoSQLBaseDocument")# 与 MongoDB 数据库交互的基础文档类 class NoSQLBaseDocument(BaseModel, Generic[T], ABC):id: UUID4 Field(default_factoryuuid.uuid4)def __eq__(self, value: object) -> bool…...

2025 香港 Web3 嘉年华:全球 Web3 生态的年度盛会

自 2023 年首届香港 Web3 嘉年华成功举办以来,这一盛会已成为全球 Web3 领域规模最大、影响力最深远的行业活动之一。2025 年 4 月 6 日至 9 日,第三届香港 Web3 嘉年华将在香港盛大举行。本届活动由万向区块链实验室与 HashKey Group 联合主办、W3ME 承…...

ERC-6909 最小多代币标准

ERC-6909 Token标准是 ERC-1155 Token标准的一种简化替代方案。 ERC-1155 标准引入了一种多Token接口,使得单个智能合约能够结合可替代的和不可替代的Token(即,​ERC20 和 ERC721)。 ERC-1155 解决了多个挑战,例如降…...

07-单链表-单链表基本操作

题目 来源 826. 单链表 - AcWing题库 思路 详见代码,主要思想就是用数组来模拟链表的创建。数组其实跟静态链表等价,由于动态链表动态new对于大数据太过于耗时,因此采用数组的方式。那数组如何起到链表的效果?用下标来索引。 …...

FFMPEG录制远程监控摄像头MP4

手绘效果图 上图是录制功能的HTML前端页面,录制功能和解码视频放在一起。录制功能关键是录制(开始录制按钮)、停止录像按钮。当点击“录制”的时候则会开始录制MP4文件, 当点击停止的时候就会停止录制MP4。经过录制后,则会生成MP4,并放到我的RV1126的/tm…...

Spring Boot 的自动装配

Spring Boot 的自动装配(Auto Configuration)是其核心特性之一,通过智能化的条件判断和配置加载机制,极大简化了传统 Spring 应用的配置复杂度。其原理和实现过程可概括为以下几个关键点: 一、核心触发机制&#xff1a…...

Python中的“泛型”和“多重继承”

“泛型”和“多重继承”属于 Python 的语法规则。 1. 泛型(Generic[T]) 通俗解释 泛型允许你在定义类或函数时,不指定具体的类型,而是使用一个“占位符”(通常命名为 T)。这就像你制作一个盒子&#xff0…...

【C++】多参数构造函数使用explict的情形

在 C 中,“无非默认值” 指的是:构造函数的参数没有设置默认值(即所有参数都必须显式传递)。这个说法通常出现在讨论多参数构造函数是否需要使用 explicit 关键字时。 具体解释 多参数构造函数: • 如果一个构造函数有…...

C# Unity 唐老狮 No.10 模拟面试题

本文章不作任何商业用途 仅作学习与交流 安利唐老狮与其他老师合作的网站,内有大量免费资源和优质付费资源,我入门就是看唐老师的课程 打好坚实的基础非常非常重要: Unity课程 - 游习堂 - 唐老狮创立的游戏开发在线学习平台 - Powered By EduSoho C# 1. 内存中,堆和…...

使用DeepSeek,优化斐波那契数函数,效果相当不错

下面这段代码定义了一个递归函数 fibonacci&#xff0c;用于计算第 n 个斐波那契数。 def fibonacci(n):if n < 1:return nelse:return fibonacci(n - 1) fibonacci(n - 2)虽然代码逻辑正确&#xff0c;但其性能较差&#xff0c;尤其是对于较大的 n 值&#xff0c;其复杂度…...

【GPT入门】第22课 langchain LCEL介绍

【GPT入门】第22课 langchain LCEL介绍 1. LCEL介绍与特点2. 原生API与LCEL的对比2. 简单demo 1. LCEL介绍与特点 LCEL 即 LangChain Expression Language&#xff0c;是 LangChain 推出的一种声明式语言&#xff0c;用于简化和优化在 LangChain 框架内构建复杂链和应用的过程…...

市场监管总局升级12315平台 专项整治四大市场顽疾保障消费安全

大湾区经济网湾区财经讯&#xff0c;在今天下午举行的国务院新闻办新闻发布会上&#xff0c;市场监管总局负责人表示&#xff0c;将开展食品非法添加、假冒伪劣、价格欺诈、虚假宣传四大领域专项整治行动&#xff0c;并强化缺陷产品召回监管&#xff0c;全面保障消费者“安全消…...