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

原型模式的实现

1. 引言

1.1 背景

在实际编程中,有时需要频繁创建多个相似但稍有不同的对象。如果采用传统的对象创建方式,容易造成代码冗余,对象重复初始化操作也可能带来大量的的资源消耗(如时间、内存等)。这样不仅降低了灵活性,导致难以适应状态的变化,还降低了代码的可扩展性。

public class Demo {
    public static void main(String[] args) {
        // 创建原型对象
        A a = getA();
        
        B b = new B();
        b.setParam(a.getParam());        
         // ...
        System.out.println("B: " + b);        C c = new C();
        c.setPartam(b.getPartam());
        // ...
        System.out.println("C: " + c);
    }
}

在面向对象编程的世界里,为了帮助开发者写出更高质量、更易于维护代码的一套解决方案。针对此类问题的,提供了原型模式。原型模式(Prototype Pattern)是一种创建型设计模式,它通过复制现有实例来创建新对象,避免了重复的初始化操作。适用于对象的创建过程昂贵、复杂或者外部变化频繁的情况。在需要快速创建复杂对象副本的业务中,可以通过原型模式避免每次都重新初始化所带来的开销。


1.2 目的

本文将详细介绍原型模式的基本概念、实现步骤。通过本篇文章,你将能够理解原型模式的工作原理,并学会如何在实际项目中有效地利用它。


2. 何为原型模式?

一句话概括,就是使用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象。

2.1 原型模式的目的

原型模式的核心目的是通过复制现有的对象来创建新对象,从而避免昂贵的对象创建过程。这在某些场景下尤为有用,例如:

创建成本高:对象的创建成本(如时间、资源)非常高。
复杂对象:对象有很多复杂的结构,初始化过程复杂且耗时。
需要创建多个相似对象:频繁需要创建多个相似但稍有不同的对象。

2.2 原型模式适合的场景

  1. 对象重复创建:在需要频繁创建类似对象并减少初始化开销的场景下。
  2. 对象初始化复杂:对象的创建过程涉及大量计算或资源分配,通过克隆可以避免这些开销。
  3. 不同配置的对象:需要创建多个配置类似但具体值不同的对象时,通过克隆基准对象进行调整。

2.3 为什么不直接使用Clone方法复制类?

直接在需要复制的类中调用 clone 方法当然是简单的实现方式,但也有一些局限性:

  1. 破坏封装:直接调用 clone 方法可能会破坏类的封装,导致类内部的实现细节暴露。
  2. 不支持多态性:使用接口或抽象类,有助于处理多个不同类型的对象。用户可以通过接口调用 clone 方法,从而实现多态性,而直接调用 clone 方法无法做到这一点。
  3. 可能需要深拷贝:有些对象需要深拷贝(对引用类型的成员进行拷贝),直接的 clone 方法可能无法满足这一需求。通过接口或抽象类可以更灵活地实现深拷贝逻辑。

2.4 浅拷贝和深拷贝&原型模式的关联

在讨论原型模式时,深拷贝和浅拷贝是两个非常重要的概念。它们与原型模式密切相关,因为原型模式涉及到对象的复制,而对象的复制又可以分为浅拷贝和深拷贝两种方式。

何为浅拷贝?
浅拷贝(Shallow Copy)在对象复制过程中,只复制对象的基本数据类型字段,对于引用类型字段,只复制引用,不复制引用对象本身。这意味着浅拷贝后的新对象与原对象共享相同的引用对象。在 Java 中,可以使用 Object 类的 clone 方法来实现浅拷贝。默认的 clone 方法进行的是浅拷贝:

public class ShallowCopyExample implements Cloneable {private int value;private int[] array;public ShallowCopyExample(int value, int[] array) {this.value = value;this.array = array;}@Overrideprotected ShallowCopyExample clone() {try {return (ShallowCopyExample) super.clone();} catch (CloneNotSupportedException e) {throw new RuntimeException(e);}}// Getters and setters...public static void main(String[] args) {int[] array = {1, 2, 3};ShallowCopyExample original = new ShallowCopyExample(42, array);ShallowCopyExample cloned = original.clone();System.out.println("初始的数组: " + original.getArray()[0]); // 1System.out.println("克隆对象的数组: " + cloned.getArray()[0]); // 1// 修改克隆对象的数组cloned.getArray()[0] = 99;System.out.println("初始的数组: " + original.getArray()[0]); // 99System.out.println("克隆对象的数组: " + cloned.getArray()[0]); // 99}
}

如上所示,修改克隆对象的数组会影响原始对象的数组,这是因为它们共享相同的引用。

何为深拷贝?
深拷贝(Deep Copy)在对象复制过程中,除了复制对象的基本数据类型字段,还递归复制引用类型字段所引用的对象。这意

相关文章:

原型模式的实现

1. 引言 1.1 背景 在实际编程中,有时需要频繁创建多个相似但稍有不同的对象。如果采用传统的对象创建方式,容易造成代码冗余,对象重复初始化操作也可能带来大量的的资源消耗(如时间、内存等)。这样不仅降低了灵活性,导致难以适应状态的变化,还降低了代码的可扩展性。 …...

【第二套】华为 2024 年校招-硬件电源岗

1.为了避免 50Hz 的电⽹电压⼲扰放⼤器,应该⽤那种滤波器: A.带阻滤波器 B.带通滤波器 C.低通滤波器 D.⾼通滤波器 2.PID 中的 I 和 D 的作⽤分别是? A、消除静态误差和提⾼动态性能 B、消除静态误差和减⼩调节时间 C、提⾼动态性能和减⼩超调…...

Xilinx FPGA:vivado利用单端RAM/串口传输数据实现自定义私有协议

一、项目要求 实现自定义私有协议,如:pc端产生数据:02 56 38 ,“02”代表要发送数据的个数,“56”“38”需要写进RAM中。当按键信号到来时,将“56”“38”读出返回给PC端。 二、信号流向图 三、状态…...

Spark on k8s 源码解析执行流程

Spark on k8s 源码解析执行流程 1.通过spark-submit脚本提交spark程序 在spark-submit脚本里面执行了SparkSubmit类的main方法 2.运行SparkSubmit类的main方法,解析spark参数,调用submit方法 3.在submit方法里调用doRunMain方法,最终调用r…...

粤港联动,北斗高质量国际化发展的重要机遇

今年是香港回归27周年,也是《粤港澳大湾区发展规划纲要》公布5周年,5年来各项政策、平台不断为粤港联动增添新动能。“十四五”时期的粤港澳大湾区,被国家赋予了更重大的使命,国家“十四五”《规划纲要》提出,以京津冀…...

Chrome导出cookie的实战教程

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

视频文字转语音经验笔记

自媒体视频制作的一些小经验,分享给大家。 一、音频部分: 1、文字转语音阐述: 微软语音识别 云希-青年男, 0.5-0.8变速 。注:云泽-中年男(不支持长音频录制), 适合郑重场合&#…...

视频融合共享平台LntonCVS统一视频接入平台智慧安防应用方案

安防视频监控平台LntonCVS是一款拥有强大拓展性和灵活部署能力的综合管理平台。它支持多种主流标准协议,包括国标GB28181、RTSP/Onvif、RTMP等,同时兼容各厂家的私有协议和SDK,如海康Ehome、海大宇等。LntonCVS不仅具备传统安防视频监控功能&…...

使用Python绘制动态螺旋线:旋转动画效果

文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Pygame绘制螺旋线函数主循环 完整代码 引言 螺旋线是一个具有美学和数学魅力的图形。通过编程,我们可以轻松创建动态旋转的螺旋线动画。在这篇博客中,我们将使用Python和Pygame库来实现…...

Symfony实战手册:PHP框架的高级应用技巧

引言 Symfony是一个功能强大且广泛应用于PHP应用程序开发的框架,它提供了许多高级特性和工具,可以帮助开发人员更高效地构建和管理复杂的Web应用程序。以下是Symfony框架的几个关键方面及其高级应用技巧: 1. 路由和控制器 Symfony的路由组…...

TOGAF培训什么内容?参加TOGAF培训有什么好处?考试通过率多少?

TOGAF培训什么内容?参加TOGAF培训有什么好处?考试通过率多少? TOGAF培训哪些内容? 通过本课程,你将掌握TOGAF的理论和实践,理解企业架构的影响,能够评估、启动、设 计、执行新一轮企业和IT架构…...

keepalived HA nginx方案

安装 centos: yum -y install epel-release yum -y install nginx keepalivedkeepalived配置解析 /etc/keepalived/keepalived.conf ! Configuration File for keepalived # 全局变量 global_defs {router_id nginx_ha # 主从保持一致script_user root # 执行健康检查的…...

报错:pathspec ‘xxx‘ did not match any file(s) known to git

在 escode 中进行分支切换时报如下错误 PS > git checkout xxx error: pathspec xxx did not match any file(s) known to git远程分支已经在 gitlab 客户端手动创建,在 escode 中也使用了拉取之类的操作,但是切换分支时依然报错。 解决方案 查看分…...

sed 保持空间命令之 x 的执行逻辑

目录 1. 将模式空间和保持空间的内容互换并打印 2. 将保持空间的内容交换回模式空间 3. 使用保持空间保存状态信息 4. 交换模式空间与保持空间隔行匹配 sed 有两个内置的缓存空间: 模式空间:该空间是 sed 内置的一个缓冲区,是 sed 执行的…...

按位异或^

在 Python 中,a ^ b 表示按位异或运算符。按位异或运算符对整数的每一位进行运算,如果对应位上的两个二进制数字不同,则结果为 1,否则为 0。 示例 a 5 # 二进制: 0101 b 3 # 二进制: 0011result a ^ b print(result) # 输…...

《企业实战分享 · 常用运维中间件》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 近期刚转战 CSDN,会严格把控文章质量,绝不滥竽充数,如需交流&#xff…...

PyCharm 2024.1简介

PyCharm 2024.1 是JetBrains公司发布的Python集成开发环境(IDE)的最新版本。作为一个深受开发者欢迎的工具,PyCharm以其强大的功能和高效的开发体验著称。以下是PyCharm 2024.1的主要特性和改进: 1. **性能提升**: …...

终身免费的Navicat数据库,不需要破解,官方支持

终身免费的Navicat数据库,不需要破解,官方支持 卸载了Navicat,很不爽上干货,Navicat免费版下载地址 卸载了Navicat,很不爽 公司不让用那些破解的数据库软件,之前一直使用Navicat。换了几款其他的数据库试了…...

Spring Boot中的模板引擎选择与配置

Spring Boot中的模板引擎选择与配置 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们来聊聊Spring Boot中的模板引擎选择与配置。模板引擎是生成动态网页…...

4、音视频封装格式---FLV

FLV FLV是一种容器封装格式,是由Adobe公司发布和维护的,用于将视频编码流与音频编码流进行封装。对于任意一种封装格式,都有其头部区域与数据区域,在FLV中,称之为FLV Header与Body。 对于FLV Header,一个FL…...

XCTF-web-easyupload

试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制&#xff0…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来&#xf…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

数据库——redis

一、Redis 介绍 1. 概述 Redis(Remote Dictionary Server)是一个开源的、高性能的内存键值数据库系统,具有以下核心特点: 内存存储架构:数据主要存储在内存中,提供微秒级的读写响应 多数据结构支持&…...