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

设计模式之原型模式

文章目录

  • 一、介绍
  • 二、实现步骤
  • 三、案例
  • 四、应用
  • 五、细胞分裂
  • 六、改造细胞分裂逻辑
  • 七、总结

一、介绍

原型模式属于创建型设计模式,用于创建重复的对象,且同时又保证了性能

该设计模式的好处是将对象的创建与调用方分离

其目的就是**根据一个对象(称为原型)创建一个与其完全相同的对象(当然内存地址不同)。**原对象被认为是新对象的原型。

二、实现步骤

原型模式的实现步骤如下:

  • 应用原型模式的类要实现Cloneable接口
  • 应用原型模式的类要重写Object类定义的clone()方法
  • 通过调用对象的clone()方法,获得一个与该对象相同的对象。

在重写Object类定义的clone()方法时,直接通过调用super.clone()即可得到一个新对象,如下所示

@Override
public Object clone() {try {Object obj = super.clone();return obj;} catch (CloneNotSupportedException e) {throw new AssertionError();}
}

super.clone()调用的其实就是在Object类中定义的方法

public class Object {// ...protected native Object clone() throws CloneNotSupportedException;// ...
}

该方法由native关键字修饰,表明其具体实现逻辑在JVM中已经完成了,我们无需知道其细节,只需知道调用该方法后将返回一个具有相同属性的对象即可。也正因此,该方式要比我们创建实例再初始化实例的性能好。

另外,该方法显式地抛出了CloneNotSupportedException异常,要求我们在调用clone()方法的对象必须实现Cloneable接口,否则将抛出该异常。

注意:调用super.clone()时,只能够满足浅拷贝,如果要实现深拷贝,则需要我们根据实际情况重写clone()的具体逻辑而不是调用super.clone()

三、案例

我们创建一个Person类,实现Cloneable接口,并重写clone()方法。

public class Person implements Cloneable{private String name;private Integer age;private String sex;// 省略get、set方法@Overridepublic Person clone() {try {Person person = (Person) super.clone();return person;} catch (CloneNotSupportedException e) {throw new AssertionError();}}
}

然后进行测试

public class PrototypeTest {public static void main(String[] args) {Person person = new Person();person.setName("name");person.setAge(1);person.setSex("男");Person clone = person.clone();System.out.println("获得的新对象:" + clone);}
}

得到的输出如下,可以发现,通过clone()方法可以获得一个与原对象具有相同属性的新对象。

在这里插入图片描述

四、应用

原型模式在实际应用中不是很广泛,因为绝大多数实例要么是有状态的(例如持有文件、远程链接等),则无法应用原型模式;要么是无状态的,此时应用单例模式更合适。

思来想去,基于原型模式创建重复对象的作用,我们可以利用该模式模拟细胞分裂

五、细胞分裂

按照上面案例,我们新建一个细胞类Cell

public class Cell implements Cloneable{// 当前细胞为第num次分裂所得,细胞分裂是一个1变2,2变4,4变8的过程,private Integer num = 0;@Overridepublic Cell clone() {try {// 每当克隆一次,num+1num++;Cell clone = (Cell) super.clone();return clone;} catch (CloneNotSupportedException e) {throw new AssertionError();}}
}

演示细胞分裂过程

public static void cellDivision() {// 第一个细胞Cell cell1 = new Cell();System.out.println("cell1:" + cell1);// cell1 通过自我复制, 产生一个新细胞 cell2Cell cell2 = cell1.clone();System.out.println("第一次分裂后:");System.out.println("cell1:" + cell1);System.out.println("cell2:" + cell2);// cell1、cell2 通过自我复制, 产生新细胞 cell3、cell4Cell cell3 = cell1.clone();Cell cell4 = cell2.clone();System.out.println("第二次分裂后:");System.out.println("cell1:" + cell1);System.out.println("cell2:" + cell2);System.out.println("cell3:" + cell3);System.out.println("cell4:" + cell4);
}

输出如下:

在这里插入图片描述

此时如果要计算当前一共有多少个细胞,就可以通过 2 n u m 2^{num} 2num得到结果。

六、改造细胞分裂逻辑

我们将N个细胞(无论分裂多少次)作为一个整体,假设该整体中所有细胞同时分裂,则可以将该细胞整体进行抽象。如下所示,新建一个细胞整体类Cells

  • 实现Cloneable接口,表示该细胞整体可进行复制分裂。
  • 重写clone()方法,该细胞整体分裂的过程,其实就是所有个体在分裂,最后将其整合即可
public class Cells implements Cloneable{// 该细胞整体中的所有细胞个体private List<Cell> cellList = new ArrayList<>();// 添加一个细胞public void addCell(Cell cell) {cellList.add(cell);}// 该细胞整体复制分裂的过程@Overridepublic Cells clone() {try {System.out.println("第" + (cellList.get(0).getNum()+1) + "次分裂...");// 新增的细胞数量和原细胞数量相同List<Cell> clonedCellList = new ArrayList<>(cellList.size());for (Cell cell : cellList) {// 将每一个细胞分裂得到的新细胞添加到clonedCellList集合中clonedCellList.add(cell.clone());}// 新细胞与原细胞合并cellList.addAll(clonedCellList);// 复制该细胞整体Cells clone = (Cells) super.clone();clone.setCellList(cellList);System.out.println("分裂后得到细胞数:" + cellList.size());return clone;} catch (CloneNotSupportedException e) {throw new AssertionError();}}
}

下面我们对该细胞整体的分裂过程进行演示

public static void cellDivision() {// 第一个细胞Cell cell = new Cell();// 向该细胞整体中添加第一个细胞Cells cells = new Cells();cells.addCell(cell);// 细胞分裂10次for (int i = 0; i < 10; i++) {cells = cells.clone();}
}

输出如下:

在这里插入图片描述

七、总结

  • 原型模式用于创建具有相同属性的重复对象。
  • 原型模式的实现就是实现Cloneable接口 + 重写clone()方法实现的。
  • Object类的clone()方法实现由JVM实现,性能较好。但仅能实现浅拷贝。


纸上得来终觉浅,绝知此事要躬行。

————————我是万万岁,我们下期再见————————

相关文章:

设计模式之原型模式

文章目录 一、介绍二、实现步骤三、案例四、应用五、细胞分裂六、改造细胞分裂逻辑七、总结 一、介绍 原型模式属于创建型设计模式&#xff0c;用于创建重复的对象&#xff0c;且同时又保证了性能。 该设计模式的好处是将对象的创建与调用方分离。 其目的就是**根据一个对象…...

正则表达式在网页处理中的应用四则

正则表达式在网页处理中的应用四则 正则表达式(Regular Expression)为字符串模式匹配提供了一种高效、方便的方法。几乎所有高级语言都提供了对正则表达式的支持,或者提供了现成的代码库供调用。本文以ASP环境中常见的处理任务为例,介绍正则表达式的应用技巧。 一、检验密…...

ping使用方法

文章目录 1、Ping的基础知识2、Ping命令详解3、怎样使用Ping这命令来测试网络连通&#xff1f;4、如何用Ping命令来判断一条链路好坏&#xff1f;5、对Ping后返回信息的分析1.Request timed out2.Destination host Unreachable 1、Ping的基础知识 ping命令相信大家已经再熟悉不…...

“心理健康人工智能产学研创新联盟”揭牌成立|深兰科技

8月14日上午&#xff0c;“2023树洞救援年会”在上海举行&#xff0c;会上举行了“心理健康人工智能产学研创新联盟”的签约和揭牌仪式。“树洞行动救援团”创始人深兰科技科学院智能科学首席科学家、荷兰阿姆斯特丹自由大学人工智能系终身教授黄智生&#xff0c;深兰科技集团创…...

FastDFS+Nginx - 本地搭建文件服务器同时实现在外远程访问「端口映射」

文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…...

Mybatis-动态sql和分页

目录 一.什么是Mybatis动态分页 二.mybatis中的动态SQL 在BookMaaper.xml中写sql BookMapper BookBiz接口类 BookBizImpl实现接口类 demo测试类 ​编辑 测试结果 三.mybatis中的模糊查询 mybatis中的#与$有是什么区别 在BookMapper.xml里面建立三个模糊查询 ​编辑 …...

基于YOLOV8模型的西红柿目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOV8模型的西红柿目标检测系统可用于日常生活中检测与定位西红柿目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算法训练数…...

数学建模及数据分析 || 4. 深度学习应用案例分享

PyTorch 深度学习全连接网络分类 文章目录 PyTorch 深度学习全连接网络分类1. 非线性二分类2. 泰坦尼克号数据分类2.1 数据的准备工作2.2 全连接网络的搭建2.3 结果的可视化 1. 非线性二分类 import sklearn.datasets #数据集 import numpy as np import matplotlib.pyplot as…...

数据分析15——office中的Excel基础技术汇总

0、前言&#xff1a; 这部分总结就是总结每个基础技术的定义&#xff0c;在了解基础技术名称和定义后&#xff0c;方便对相关技术进行检索学习。笔记不会详细到所有操作都说明&#xff0c;但会把基础操作的名称及作用说明&#xff0c;可自行检索。本文对于大部分读者有以下作用…...

C语言好题解析(四)

目录 选择题一选择题二选择题三选择题四选择题五编程题一 选择题一 已知函数的原型是&#xff1a; int fun(char b[10], int *a); 设定义&#xff1a; char c[10];int d; &#xff0c;正确的调用语句是&#xff08; &#xff09; A: fun(c,&d); B: fun(c,d); C: fun(&…...

英语——主谓一致

主谓一致是指句子的谓语动词与其主语在数上必须保持一致,一般遵循以下三个原则: 一、语法形式上一致,即单复数形式与谓语要一致。 二、意义上一致,即主语意义上的单复数要与谓语的单复数形式一致。 三、就近以及就远原则,即谓语动词的单复形式取决于最靠近它的词语或者离它…...

属性字符串解析

连续的KV的字符串&#xff0c;每个KV之间用","分隔&#xff0c;V中可嵌套KV的连续字符串结构&#xff0c;例如“ key1value1,key2value2,key3[key4value4,key5value5,key6[key7value7]],key8value8 请编写如下函数&#xff0c;给定字符串&#xff0c;输出嵌套结构的H…...

【C++初阶】vector容器

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…...

ThreadLocal深度解析

简介 在并发编程中&#xff0c;导致并发bug的问题都会归结于对共享变量的操作不当。多个线程同时读写同一共享变量存在并发问题&#xff0c;我们可以利用写时复制、不变性来突破对原数据的写操作&#xff0c;没有写就没有并发问题&#xff0c;而本篇文章所介绍的技术是突破共享…...

06有监督学习——迁移学习

1.迁移学习分类 &#xff08;1&#xff09; 基于实例的迁移学习方法&#xff1a; 假设:源域中的一些数据和目标域会共享很多共同的特征方法:对源域进行instance reweighting&#xff0c;筛选出与目标域数据相似度高的数据&#xff0c;然后进行训练学习 &#xff08;2&#x…...

快速连接服务器脚本 可从多个服务中选择并连接

使用 python 做一个可选择服务器登录连接的脚本 前置条件 需要有python 环境python --version 显示版本号即可检查 python 是否有 paramiko 包没有的话 python install paramiko创建一个python 文件,内容如下 # -*- coding: utf-8 -*-""" Authors: huxiaohua…...

MemSeg:一种差异和共性来检测图像表面缺陷的半监督方法

目录 1、摘要 2、Method 2.1 模拟异常样本 2.2 Memory Module 2.3 空间注意模块 2.4 多尺度特征融合模块 2.5 损失函数设置 2.6 Decoder模块 1、摘要 本文认为人为创建类内差异和保持类内共性可以帮助模型实现更好的缺陷检测能力&#xff0c;从而更好地区分非正常图像。如…...

迈向未来的大门:人脸识别技术的突破与应用

迈向未来的大门&#xff1a;人脸识别技术的突破与应用 人脸识别&#xff1a;人脸识别的工作流程人脸识别的作用人脸识别技术的突破与应用 在深度学习人脸识别之前我们要先知道人脸识别是什么。 人脸识别&#xff1a; 人脸识别是一种基于人脸图像或视频进行身份验证或识别的技术…...

Vue-9.集成(.editorconfig、.eslintrc.js、.prettierrc)

介绍 同时使用 .editorconfig、.prettierrc 和 .eslintrc.js 是很常见的做法&#xff0c;因为它们可以在不同层面上帮助确保代码的格式一致性和质量。这种组合可以在开发过程中提供全面的代码维护和质量保证。然而&#xff0c;这也可能增加一些复杂性&#xff0c;需要谨慎配置…...

Qt 编译使用Bit7z库接口调用7z.dll、7-Zip.dll解压压缩常用Zip、ISO9660、Wim、Esd、7z等格式文件(一)

bit7z一个c静态库&#xff0c;为7-zip共享库提供了一个干净简单的接口 使用CMAKE重新编译github上的bit7z库&#xff0c;用来解压/预览iso9660&#xff0c;WIm&#xff0c;Zip,Rar等常用的压缩文件格式。z-zip库支持大多数压缩文件格式 导读 编译bit7z(C版本)使用mscv 2017编译…...

UniApp地图组件实战:5分钟搞定腾讯位置服务+自定义气泡弹窗(附避坑指南)

UniApp腾讯地图组件深度实战&#xff1a;从Key申请到自定义弹窗全流程解析 1. 腾讯位置服务Key申请与配置 在manifest.json中配置腾讯地图Key是第一步&#xff0c;但90%的开发者会忽略安全配置细节。正确的申请流程应该是&#xff1a; 访问腾讯位置服务官网&#xff0c;进入控制…...

实时数据复制技术在大数据平台中的应用与实践

实时数据复制技术在大数据平台中的应用与实践关键词&#xff1a;实时数据复制、大数据平台、CDC&#xff08;变更数据捕获&#xff09;、数据同步、数据一致性、分布式系统、ETL摘要&#xff1a;本文深入探讨了实时数据复制技术在大数据平台中的核心应用场景与实践方法。我们将…...

技术深度解析:ER-Save-Editor如何实现跨平台艾尔登法环存档编辑

技术深度解析&#xff1a;ER-Save-Editor如何实现跨平台艾尔登法环存档编辑 【免费下载链接】ER-Save-Editor Elden Ring Save Editor. Compatible with PC and Playstation saves. 项目地址: https://gitcode.com/GitHub_Trending/er/ER-Save-Editor 艾尔登法环存档编辑…...

Paste 轻量级剪贴板管理工具使用指南

Paste 轻量级剪贴板管理工具使用指南 【免费下载链接】paste A no-datastore, client-side paste service. 项目地址: https://gitcode.com/gh_mirrors/past/paste 一、场景化导入&#xff1a;当剪贴板成为你的效率瓶颈 想象一下这样的工作场景&#xff1a;你正在整理一…...

FireRed-OCR StudioGPU适配方案:多卡并行解析长文档的配置详解

FireRed-OCR StudioGPU适配方案&#xff1a;多卡并行解析长文档的配置详解 1. 工业级文档解析工具概述 FireRed-OCR Studio是一款基于Qwen3-VL模型开发的下一代文档解析工具&#xff0c;专为处理复杂文档场景设计。它不仅能够精准识别文字内容&#xff0c;更能完整还原文档中…...

嵌入式WiFi开发 | 基于wireless_tools的交叉编译实战与移植指南

1. 嵌入式WiFi开发入门&#xff1a;为什么需要wireless_tools&#xff1f; 在嵌入式Linux开发中&#xff0c;网络连接能力往往是刚需。想象一下你的智能家居设备需要自动连接路由器&#xff0c;或者工业传感器需要通过WiFi上传数据——这些都离不开可靠的无线网络配置工具。这就…...

.NET校招真实面经:手写代码、项目深挖、算法到底考什么

文章目录写在前面&#xff1a;校招面试就像相亲&#xff0c;你得先过了"眼缘"这一关第一部分&#xff1a;手写代码——别做"嘴强王者"&#xff0c;要做"手速达人"1.1 面试官为啥非要你手写代码&#xff1f;1.2 .NET校招手写代码到底考啥&#xf…...

突破网盘下载限制:直链解析工具的技术实现与应用指南

突破网盘下载限制&#xff1a;直链解析工具的技术实现与应用指南 【免费下载链接】Online-disk-direct-link-download-assistant 可以获取网盘文件真实下载地址。基于【网盘直链下载助手】修改&#xff08;改自6.1.4版本&#xff09; &#xff0c;自用&#xff0c;去推广&#…...

终极AI系统提示词泄露指南:如何解密顶级AI的核心指令集 [特殊字符]

终极AI系统提示词泄露指南&#xff1a;如何解密顶级AI的核心指令集 &#x1f50d; 【免费下载链接】system_prompts_leaks 项目地址: https://gitcode.com/GitHub_Trending/sy/system_prompts_leaks 想要深入了解ChatGPT、Claude、Gemini等顶级AI助手的工作原理吗&…...

uniapp 抖音生态集成实战:从授权登录到内容发布与社交分享

1. 为什么要在uniapp中集成抖音生态&#xff1f; 对于电商类或内容社区类的uniapp应用来说&#xff0c;抖音生态的集成价值主要体现在三个方面&#xff1a;流量获取、用户增长和内容传播。抖音作为国内最大的短视频平台之一&#xff0c;拥有庞大的用户群体和活跃的内容生态。通…...