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

二十三种设计模式-原型模式

原型模式(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):实现原型接口,提供具体的克隆实现,生成自己的副本。

实现步骤

  1. 实现Cloneable接口:让类实现Cloneable接口,表示该类的对象可以被克隆。
  2. 重写clone()方法:在类中重写Object类的clone()方法,以实现深拷贝或浅拷贝。
  3. 创建原型对象:创建一个原型对象,作为后续克隆的模板。
  4. 克隆原型对象:通过调用原型对象的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脚本语言…...

易支付二次元网站源码及部署教程

易支付二次元网站源码及部署教程 引言 在当今数字化时代,二次元文化逐渐成为年轻人生活中不可或缺的一部分。为了满足这一庞大用户群体的需求,搭建一个二次元主题网站显得尤为重要。本文将为您详细介绍易支付二次元网站源码的特点及其部署教程&#xf…...

ios脚本巨魔商店多巴胺越狱基本操作教程

准备工作 确认设备兼容性:A9-A11(iPhone6s-X):iOS15.0-16.6.1;A12-A14(iPhoneXR-12PM):iOS15.0-16.5.1;A15-A16(iPhone13&#xff0d…...

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…...

汽车供应链关键节点:物流采购成本管理全解析

在汽车行业,供应链管理是一项至关重要的任务。汽车制造从零部件的生产到整车的交付,涉及多个环节,其中物流、采购与成本管理是核心节点。本文将深入分析这些关键环节,探讨如何通过供应商管理系统及相关工具优化供应链管理。 一、…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析,分为​​已启动​​和​​未启动​​两种场景: 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​:当其他组件(如Activity、Service)通过ContentR…...

windows系统MySQL安装文档

概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...