二十三种设计模式-原型模式
原型模式(Prototype Pattern)是一种创建型设计模式,它通过拷贝现有的实例来创建新的实例,而不是通过新建实例。这种方式可以避免复杂的构造过程,同时还能保持对象的创建和使用分离,提高系统的灵活性和扩展性。
了解原型模式之前需要先搞懂浅拷贝和深拷贝。
浅拷贝指的是创建一个新对象,然后将原对象的非静态字段复制到新对象中。如果字段是基本数据类型,那么直接复制其值;如果字段是对象引用,则复制引用本身,而不是引用的对象。这意味着新对象和原对象的引用字段指向同一个对象。
深拷贝意味着不仅要复制对象本身,还要复制对象中所有引用的对象,以及这些引用对象中引用的其他对象,直到所有相关对象都被复制。
另外java中有一些特殊的引用类型(不可变对象),如下。这些引用类型创建的对象是不可变对象,在拷贝是都是理解成是一种深拷贝。
在Java中,不可变对象是指一旦创建后,其状态(即对象的字段值)就不能被改变的对象。不可变对象具有线程安全性、可缓存性和可共享性等优点。以下是一些常见的不可变引用类型对象:基本数据类型的包装类
Integer
Byte
Short
Long
Float
Double
Character
Boolean
这些包装类都是基本数据类型的对应引用类型。它们是不可变的,因为它们的值一旦被设置,就不能被改变。例如,当你对一个Integer对象进行加法运算时,实际上会创建一个新的Integer对象来表示新的值,而不是修改原来的对象。字符串类
String
String类是Java中最常用的不可变类之一。字符串对象一旦被创建,其内容就不能被改变。例如,当你使用+操作符连接两个字符串时,会创建一个新的字符串对象,而不是修改原来的字符串对象。原子类
AtomicInteger
AtomicLong
AtomicBoolean
其他java.util.concurrent.atomic包中的原子类
这些原子类提供了对基本数据类型的安全操作,它们是不可变的,因为它们的值只能通过原子操作来更新,而不是直接修改对象的状态。其他不可变类
BigDecimal 和 BigInteger
这些类用于表示任意精度的数值。它们是不可变的,因为每次进行数学运算时,都会返回一个新的对象来表示结果,而不是修改原来的对象。java.time包中的日期和时间类
例如:LocalDate
LocalTime
LocalDateTime
ZonedDateTime
Duration
Period
这些类是Java 8引入的新的日期和时间API的一部分。它们都是不可变的,每次进行日期或时间的修改操作时,都会返回一个新的对象。不可变对象的设计原则
要设计一个不可变对象,通常需要遵循以下原则:所有字段都是final的:确保字段一旦被初始化,就不能被改变.
不提供修改字段值的方法:不提供任何可以修改对象状态的方法.
确保对象的所有字段都是不可变的:如果对象的字段是引用类型,确保这些引用类型也是不可变的.
如果需要提供访问字段的方法,返回字段的副本而不是引用:例如,对于包含可变对象的字段,返回字段的副本,以防止外部代码修改对象的状态.
通过设计不可变对象,可以提高程序的安全性和可维护性,特别是在多线程环境中.
原型模式核心概念
- 原型(Prototype):声明一个克隆自身的接口,用于创建当前对象的副本。在Java中,通常通过实现
Cloneable接口并重写clone()方法来实现原型模式。 - 具体原型(ConcretePrototype):实现原型接口,提供具体的克隆实现,生成自己的副本。
实现步骤
- 实现
Cloneable接口:让类实现Cloneable接口,表示该类的对象可以被克隆。 - 重写
clone()方法:在类中重写Object类的clone()方法,以实现深拷贝或浅拷贝。 - 创建原型对象:创建一个原型对象,作为后续克隆的模板。
- 克隆原型对象:通过调用原型对象的
clone()方法,创建新的对象实例.
示例代码
以下是一个简单的Java示例,展示如何使用原型模式:
import java.util.Date;// 具体原型类
class Resume implements Cloneable {private String name;private String sex;private String age;private Date birthDate; // 假设包含日期对象public Resume(String name, String sex, String age) {this.name = name;this.sex = sex;this.age = age;this.birthDate = new Date(); // 初始化日期对象}@Overrideprotected Object clone() throws CloneNotSupportedException {// 实现深拷贝//super.clone()是调用Object类的clone()方法,它会创建一个新的对象,并将原对象的字段值复制到新对象中。对于基本数据类型的字段,值会被直接复制;而对于引用类型的字段,复制的是引用本身,而不是引用所指向的对象. 这一步本身是浅拷贝.Resume clonedResume = (Resume) super.clone();clonedResume.birthDate = (Date) this.birthDate.clone();return clonedResume;}@Overridepublic String toString() {return "Resume{" +"name='" + name + '\'' +", sex='" + sex + '\'' +", age='" + age + '\'' +", birthDate=" + birthDate +'}';}
}public class PrototypePatternDemo {public static void main(String[] args) throws CloneNotSupportedException {Resume originalResume = new Resume("John Doe", "Male", "30");System.out.println("Original Resume: " + originalResume);Resume clonedResume = (Resume) originalResume.clone();System.out.println("Cloned Resume: " + clonedResume);}
}
优缺点
- 优点:
- 性能优势:通过拷贝现有对象,避免了复杂的构造过程,特别是在对象创建过程中需要进行大量数据计算或资源获取时.
- 代码简洁:简化了对象的创建代码,使得代码更加简洁和易于维护.
- 缺点:
- 实现复杂:需要实现深拷贝,对于包含复杂对象引用的类,实现起来可能比较复杂.
- 对类的约束:需要实现
Cloneable接口,并且所有涉及的对象都需要支持拷贝操作,这可能对类的设计有一定的约束.
适用场景
- 当一个系统应该独立于其产品的创建、组合和表示时.
- 当需要通过动态指定创建对象的类别、数目和初始化参数时.
- 当对象的创建过程复杂,且需要避免重复创建大量相似对象时.
相关文章:
二十三种设计模式-原型模式
原型模式(Prototype Pattern)是一种创建型设计模式,它通过拷贝现有的实例来创建新的实例,而不是通过新建实例。这种方式可以避免复杂的构造过程,同时还能保持对象的创建和使用分离,提高系统的灵活性和扩展性…...
提升汽车金融租赁系统的效率与风险管理策略探讨
内容概要 在汽车金融租赁系统这个复杂的生态中,提升整体效率是每个企业都渴望达成的目标。首先,优化业务流程是实现高效运行的基础。通过分析目前的流程,找出冗余环节并进行简化,能够帮助企业缩短审批时间,提高客户满…...
Spring Framework 5.3.x源码构建 (jdk-1.8, gradle 7.5.1, idea2024.3)
1、下载jdk安装并配置环境变量(自行百度) https://www.oracle.com/java/technologies/downloads/#java8 2、下载spring-framework源码,切换分支到5.3.x https://github.com/spring-projects/spring-framework.git 备用地址 https://gitco…...
leetcode 2241. 设计一个 ATM 机器 中等
一个 ATM 机器,存有 5 种面值的钞票:20 ,50 ,100 ,200 和 500 美元。初始时,ATM 机是空的。用户可以用它存或者取任意数目的钱。 取款时,机器会优先取 较大 数额的钱。 比方说,你想…...
IO模型与NIO基础
File类 File类主要是JAVA为文件这块的操作(如删除、新建等)而设计的相关类File类的包名是java.io,其实现了Serializable, Comparable两大接口以便于其对象可序列化和比较 创建一个文件/文件夹 删除文件/文件夹 获取文件/文件夹 判断文件/文件夹是否存在 对文件夹进…...
上门按摩系统架构与功能分析
一、系统架构 服务端:Java(最低JDK1.8,支持JDK11以及JDK17)数据库:MySQL数据库(标配5.7版本,支持MySQL8)ORM框架:Mybatis(集成通用tk-mapper,支持…...
ubuntu安装ssh9.2
删除旧版本: dpkg --list|grep ssh apt remove sshwget https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.2p1.tar.gz tar xzvf openssh-9.2p1.tar.gz cd openssh-9.2p1 #下载依赖#开始编译安装 ./configure && make && make inst…...
linux wsl配置 redis远程连接
✅ 1. 修改 Redis 配置文件 在 WSL 的 Redis 配置文件中,找到 redis.conf 或 /etc/redis/redis.conf 文件,编辑以下配置项: ➡️ 更新 bind 配置项 将 bind 127.0.0.1 ::1 修改为: bind 0.0.0.0这样,Redis 将监听所…...
JVM 优化指南
JVM 优化指南 1. JVM 参数配置 1.1 基础参数配置 设置堆内存大小 -Xms2048m -Xmx2048m 设置新生代大小 -Xmn1024m 设置元空间大小 -XX:MetaspaceSize256m -XX:MaxMetaspaceSize256m 设置线程栈大小 -Xss512k1.2 垃圾回收器配置 使用 G1 垃圾回收器 -XX:UseG1GC 设置期望停顿…...
关机重启后,GitLab服务异常
整理机房,关闭了所有主机重新上架。 上架后开机,所有主机硬件启动正常。 其中一台GitLab服务器启动正常,使用gitlab-ctl status查看服务业正常。 但使用web登陆却失败,如下图: 反复测试,发现无论使用正确密码还是错误密码都是同样的提示。很大可能是数据库的问题。 使…...
谷粒商城-高级篇完结-Sleuth+Zipkin 服务链路追踪
1、基本概念和整合 1.1、为什么用 微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性,如果出现了错误和异常,很难去定位 。主要体现在&#…...
C语言基本知识复习浓缩版:标识符、函数、进制、数据类型
C语言基本知识复习浓缩版:标识符、函数、进制、数据类型 【c语言期末复习3小时速成【完整全集】期末速成含考试题c语言期末速成突击复习C语言补考C语言期末大一】 B站看到的复习C语言视频,感觉非常棒,就跟着进行了一下学习。众所周知&#…...
selenium已经登陆了 我怎么查看 网页 在fRequest xhr 的数据呢
在使用 Selenium 登录网页后,查看网页的 XHR 请求数据可以通过以下几种方法: ### 1. 使用浏览器开发者工具 - **手动查看**: - 打开浏览器的开发者工具(按 F12 或右键点击页面元素选择“检查”)。 - 切换到“Netw…...
Bash语言的数据库编程
Bash语言的数据库编程 引言 在现代软件开发中,数据库编程是一个不可或缺的部分。从小型项目到大型系统,数据库通常是存储和管理数据的核心。然而,许多开发者往往将焦点放在高级编程语言如Python、Java或C#上,忽视了Shell脚本语言…...
易支付二次元网站源码及部署教程
易支付二次元网站源码及部署教程 引言 在当今数字化时代,二次元文化逐渐成为年轻人生活中不可或缺的一部分。为了满足这一庞大用户群体的需求,搭建一个二次元主题网站显得尤为重要。本文将为您详细介绍易支付二次元网站源码的特点及其部署教程…...
ios脚本巨魔商店多巴胺越狱基本操作教程
准备工作 确认设备兼容性:A9-A11(iPhone6s-X):iOS15.0-16.6.1;A12-A14(iPhoneXR-12PM):iOS15.0-16.5.1;A15-A16(iPhone13-…...
ScratchLLMStepByStep:SFT之分类微调
1. 引言 前面我们花了三节内容来介绍预训练,包括如何从零搭建、如何加速运算、如何分布式加速训练,本节开始我们将进入监督微调(SFT)阶段。 常见语言模型的微调任务有两类,分类微调和指令微调。 分类微调模型通常是…...
人工智能知识分享第十天-机器学习_聚类算法
聚类算法 1 聚类算法简介 1.1 聚类算法介绍 一种典型的无监督学习算法,主要用于将相似的样本自动归到一个类别中。 目的是将数据集中的对象分成多个簇(Cluster),使得同一簇内的对象相似度较高,而不同簇之间的对象相…...
MySQL和Hive中的行转列、列转行
水善利万物而不争,处众人之所恶,故几于道💦 文章目录 MySQL1.行转列2.列转行 Hive1.行转列2.列转行(1)侧窗(2)union MySQL 1.行转列 把多行转成列。直接group,sum(if()) 2.列转行 Hive 1.行转列 select name,sum(if(kmshuxu…...
汽车供应链关键节点:物流采购成本管理全解析
在汽车行业,供应链管理是一项至关重要的任务。汽车制造从零部件的生产到整车的交付,涉及多个环节,其中物流、采购与成本管理是核心节点。本文将深入分析这些关键环节,探讨如何通过供应商管理系统及相关工具优化供应链管理。 一、…...
【ComfyUI】Qwen-Image-Edit-F2P 在Unity数字人中的应用:驱动3D角色面部表情生成
ComfyUI Qwen-Image-Edit-F2P 在Unity数字人中的应用:驱动3D角色面部表情生成 1. 引言:当AI绘画遇上3D表情动画 想象一下,你正在开发一款游戏或者制作一个虚拟偶像,角色需要做出成百上千种表情——开心的、悲伤的、惊讶的、愤怒…...
【GUI-Agent】阶跃星辰 GUI-MCP 解读---()---执行层芭
起因是我想在搞一些操作windows进程的事情时,老是需要右键以管理员身份运行,感觉很麻烦。就研究了一下怎么提权,顺手瞄了一眼Windows下用户态权限分配,然后也是感谢《深入解析Windows操作系统》这本书给我偷令牌的灵感吧ÿ…...
金融系统的测试特殊性:安全、合规与性能
对于软件测试从业者而言,金融系统的测试是一个充满独特挑战与高度专业要求的领域。这并非简单的功能验证,而是一项直接关乎资金安全、市场稳定与公众信心的系统性保障工程。其特殊性根植于金融业务本身的严肃性、高价值属性及严密的监管环境,…...
人脸特征控制与AI绘图:ComfyUI InstantID开源工具技术解析与实践指南
人脸特征控制与AI绘图:ComfyUI InstantID开源工具技术解析与实践指南 【免费下载链接】ComfyUI_InstantID 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI_InstantID 一、技术原理:精准人脸控制的底层实现机制 1.1 特征提取流程…...
Flutter 响应式设计:构建适配多设备的应用
Flutter 响应式设计:构建适配多设备的应用掌握 Flutter 响应式设计的高级技巧,创建适配不同屏幕尺寸的应用。一、响应式设计概述 作为一名追求像素级还原的 UI 匠人,我对 Flutter 响应式设计有着深入的研究。响应式设计是现代应用开发的重要组…...
Windows 11/10下Genymotion与VirtualBox的‘网络适配器战争’:彻底解决启动报错与VirtualBox Host-Only Network #N泛滥问题
Windows 11/10下Genymotion与VirtualBox的网络适配器冲突全解析 每次启动Genymotion虚拟机时,你是否注意到系统里又悄悄多出一个带编号的VirtualBox Host-Only Network适配器?这背后隐藏着Windows网络管理机制与虚拟化软件之间一场看不见的"军备竞…...
深入解析 __int128:如何高效处理超大规模整数运算
1. 为什么我们需要 __int128? 在编程的世界里,整数类型就像是不同容量的水桶。int32 是个小水桶,能装大约 20 亿的水滴;long long 是个大水桶,能装 900 多万亿的水滴。但当我们遇到需要计算 10^27 这种天文数字时&…...
7个高效技巧:用FanControl实现智能风扇精准控制
7个高效技巧:用FanControl实现智能风扇精准控制 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/FanCo…...
HOJ实战:从零部署到功能扩展的完整开发指南
1. 环境准备与基础部署 在CentOS系统上部署HOJ在线判题系统,宝塔面板是最便捷的选择。我实测过多次,用宝塔可以省去80%的配置时间。首先确保你的服务器满足最低配置要求:2核CPU、4GB内存、50GB硬盘空间。这个配置足够支撑中小规模的在线判题…...
Python内存管理机制详解:面试必问
目录 一、为什么面试官总爱问内存管理? 二、Python内存管理核心架构 三、PyObject:所有Python对象的祖先 四、引用计数:最基础的内存管理方式 1. 引用计数的工作原理 2. 循环引用 —— 引用计数的死穴 五、垃圾回收(GC&…...
