文末送书!谈谈原型模式在JAVA实战开发中的应用(附源码+面试题)

news2024/11/25 2:28:57

作者主页:Designer 小郑
作者简介:3年JAVA全栈开发经验,专注JAVA技术、系统定制、远程指导,致力于企业数字化转型,CSDN博客专家,蓝桥云课认证讲师。

本文讲解了 Java 设计模式中的原型模式,并给出了样例代码,原型模式的主要目的是通过复制或克隆现有对象来创建新对象,而无需依赖于显式的实例化过程。

在这里插入图片描述

目录

  • 一、谈谈什么是对象克隆?
  • 二、谈谈什么是深拷贝和浅拷贝,有什么区别?
    • 2.1 深拷贝
    • 2.2 浅拷贝
    • 2.3 小节
  • 三、如何解决java对象拷贝的性能问题
  • 四、学习什么是原型模式
  • 五、原型模式上手实战
  • 六、原型模式的应用场景
  • 七、原型模式面试题
  • 八、文末福利


一、谈谈什么是对象克隆?

在学习原型模式之前,首先要理解对象克隆的概念。

在Java中, 对象克隆是指创建一个现有对象的副本 \color{red}{对象克隆是指创建一个现有对象的副本} 对象克隆是指创建一个现有对象的副本,对象克隆通常用于在不影响原始对象的情况下创建一个相同状态的新对象。

Java中的对象克隆可以通过实现 Cloneable 接口和重写 clone() 方法来实现。

在使用克隆时,可以使用clone()方法创建对象的副本,该方法返回一个新的对象,该对象具有与原始对象相同的属性值。

Java 中的 clone() 方法执行的是浅拷贝,这意味着克隆的对象和原始对象共享相同的引用类型字段,如果需要实现深拷贝,即克隆对象及其所有引用类型字段的副本,就需要在 clone() 方法中进行相应的处理。

在这里插入图片描述


二、谈谈什么是深拷贝和浅拷贝,有什么区别?

在Java中, 对象拷贝可以分为浅拷贝和深拷贝两种方式 \color{red}{对象拷贝可以分为浅拷贝和深拷贝两种方式} 对象拷贝可以分为浅拷贝和深拷贝两种方式,它们之间的区别在于拷贝对象时是否创建了原始对象的副本,以及对引用类型字段的处理方式。

2.1 深拷贝

深拷贝是指创建一个新对象,该对象的字段值与原始对象完全相同,包括引用类型字段。在深拷贝中,不仅复制了对象的基本类型字段,还创建了新的对象来存储引用类型字段的副本。这意味着修改拷贝对象的引用类型字段不会影响原始对象的引用类型字段,因为它们引用的是不同的对象。

2.2 浅拷贝

浅拷贝是指创建一个新对象,该对象的字段值与原始对象完全相同,但对于引用类型字段,它们共享相同的引用。换句话说,浅拷贝只复制了对象中的基本类型字段,而对于引用类型字段,只是复制了引用,没有创建新的对象。
在浅拷贝中,修改拷贝对象的引用类型字段会影响到原始对象的引用类型字段。这是因为原始对象和拷贝对象共享相同的引用,所以它们指向相同的内存地址。

2.3 小节

实现深拷贝的方式有多种,比较常用的方法包括以下 3 3 3 点。

  • 通过实现 Serializable 接口,使用对象的序列化和反序列化来实现深拷贝。
  • 使用 Cloneable 接口和重写 clone() 方法来实现深拷贝。
  • clone() 方法中,除了调用 super.clone() 复制对象的基本类型字段外,还需要对引用类型字段进行单独的深拷贝处理。

总结起来,浅拷贝只复制对象的基本类型字段和引用类型字段的引用,而深拷贝会复制对象的基本类型字段和引用类型字段的副本。

因此,在需要保留对象独立性和避免原始对象修改的情况下,使用深拷贝是更为合适的选择。

在这里插入图片描述


三、如何解决java对象拷贝的性能问题

在Java中,对象拷贝可能面临性能问题,特别是在处理大型对象或复杂对象图时,以下是一些可以帮助解决 Java 对象拷贝性能问题的方法,给同学们提供参考。

  1. 使用原型模式:通过复制或克隆现有对象来创建新对象,而无需依赖于显式的实例化过程,从而避免了直接创建新对象的开销,原型模式可以通过实现 Cloneable 接口和重写 clone() 方法来实现。

  2. 使用浅拷贝:如果你只需要复制对象的基本类型字段,并且可以共享引用类型字段,那么浅拷贝是一个更高效的选择,浅拷贝只涉及字段的复制,因此比深拷贝更快。

  3. 使用构造函数:手动编写一个构造函数,以根据原始对象的属性创建新对象,这种方式可以避免调用 clone() 方法或实现 Cloneable 接口的开销。

  4. 使用序列化和反序列化:使用 Java 对象的序列化和反序列化机制可以实现深拷贝,通过将对象序列化为字节流,然后反序列化成新的对象,可以创建对象及其所有引用字段的完全独立副本,但序列化和反序列化也会带来一定的性能开销。

  5. 使用第三方库:有些第三方库提供了更高效的对象拷贝实现,例如 Apache Commons 库提供了 SerializationUtils.clone() 方法,用于快速实现对象的深拷贝。

  6. 使用对象池:如果你需要频繁地拷贝对象,可以考虑使用对象池,对象池在初始阶段创建一组对象,并在需要时从池中获取和返回对象,以避免频繁地创建和销毁对象。

  7. 考虑重构:有时性能问题可能源于对象本身的设计,在某些情况下,可以通过优化对象的结构或减少不必要的字段来改善性能。

在这里插入图片描述


四、学习什么是原型模式

原型模式是一种创建型设计模式 \color{red}{原型模式是一种创建型设计模式} 原型模式是一种创建型设计模式,其主要目的是通过复制或克隆现有对象来创建新对象,而无需依赖于显式的实例化过程

原型模式通过复制现有对象的状态来创建新对象,从而避免了直接创建新对象的开销,原型模式可以通过实现 Cloneable 接口和重写 clone() 方法来实现。

在原型模式中,原型对象作为被复制的对象,可以称为原型。克隆方法是原型模式的核心部分,它定义了如何复制原型对象。通过克隆方法,我们可以创建一个与原型对象具有相同状态的新对象。

原型模式的主要优点是可以在运行时动态创建对象 \color{red}{原型模式的主要优点是可以在运行时动态创建对象} 原型模式的主要优点是可以在运行时动态创建对象,避免了显式的实例化过程,提高了创建对象的效率。它还提供了一种简单的方式来创建具有相同状态的对象,通过修改克隆得到的对象,可以满足不同的需求。另外,原型模式也能够隐藏对象的创建细节,使得客户端代码与具体类解耦。

但在使用原型模式需要注意一些问题。首先克隆对象可能包含对其他对象的引用,这可能导致对象图的复制,需要特别小心处理。其次,克隆过程可能会比直接创建对象更复杂,需要对克隆方法进行合理的实现

原型模式提供了一种创建对象的简单而高效的方式,可以在运行时动态地创建具有相同状态的新对象,它在需要创建相似对象或隐藏对象创建细节时非常有用。

在这里插入图片描述


五、原型模式上手实战

以下是一个使用原型模式的 Java 代码示例,请同学们复制到本地执行。

// 原型接口
interface Prototype extends Cloneable {
    Prototype clone();
}

// 具体原型类
class ConcretePrototype implements Prototype {
    private String name;

    public ConcretePrototype(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public Prototype clone() {
        try {
            return (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ConcretePrototype prototype = new ConcretePrototype("Prototype 1");
        System.out.println("Original object: " + prototype.getName());

        ConcretePrototype clonedObject = (ConcretePrototype) prototype.clone();
        System.out.println("Cloned object: " + clonedObject.getName());

        clonedObject.setName("Prototype 2");
        System.out.println("Modified cloned object: " + clonedObject.getName());
    }
}

在上面的示例中,我们定义了一个原型接口 Prototype,其中包含了一个 clone() 方法用于复制自身对象。

然后,我们创建了一个具体的原型类 ConcretePrototype,实现了 Prototype 接口,并重写了 clone() 方法。

在客户端代码中,我们首先创建了一个原型对象 prototype,然后通过调用 clone() 方法来复制原型对象,得到一个克隆对象 clonedObject

通过修改克隆对象的属性,我们可以验证克隆对象和原型对象是相互独立的,互不影响。


六、原型模式的应用场景

原型模式通常在以下 3 3 3 类开发场景下使用,请同学们有个简单的了解。

  1. 需要创建一个对象的成本较大,例如涉及到数据库操作、网络请求等耗时操作。
  2. 需要创建的对象与已有对象具有相似的属性,只有部分属性需要修改。
  3. 需要隐藏对象的创建细节,使客户端代码与具体类解耦。

当然,还有一些应用场景,需要用到原型模式。

  1. 复杂对象的创建:当创建一个复杂对象的过程很繁琐或耗时时,可以使用原型模式来复制一个已有对象,避免重复创建。
  2. 原型注册表:使用原型模式可以创建一个对象的集合,并在需要时从集合中复制已有对象,提高对象的创建效率。
  3. 工厂方法模式的替代:原型模式可以作为工厂方法模式的替代,当需要创建的对象具有相同的基类或接口,并且只有部分属性需要修改时,原型模式比工厂方法模式更加灵活。

总之,原型模式适用于创建成本高、创建过程复杂或需要隐藏创建细节的对象,通过克隆现有对象来创建新对象,可以提高创建对象的效率,同时也能够灵活地满足不同的需求

在这里插入图片描述


七、原型模式面试题

一、什么是原型模式? \color{red}{一、什么是原型模式?} 一、什么是原型模式?

原型模式是一种创建型设计模式,通过复制或克隆现有对象来创建新对象,而无需依赖于显式的实例化过程。

二、如何实现原型模式? \color{red}{二、如何实现原型模式?} 二、如何实现原型模式?

在Java中,可以通过实现Cloneable接口和重写clone()方法来实现原型模式。clone()方法可以复制现有对象的状态,并创建一个与原型对象具有相同状态的新对象。

三、克隆方法与构造方法有什么区别? \color{red}{三、克隆方法与构造方法有什么区别?} 三、克隆方法与构造方法有什么区别?

克隆方法是在现有对象的基础上创建一个新对象,而构造方法是通过实例化类来创建新对象。克隆方法可以复制现有对象的状态,而构造方法需要手动设置新对象的状态。

四、原型模式的优点是什么? \color{red}{四、原型模式的优点是什么?} 四、原型模式的优点是什么?

原型模式可以在运行时动态创建对象,避免了显式的实例化过程,提高了创建对象的效率。它还提供了一种简单的方式来创建具有相同状态的对象,并能够隐藏对象的创建细节,使得客户端代码与具体类解耦。

五、原型模式的适用场景有哪些? \color{red}{五、原型模式的适用场景有哪些?} 五、原型模式的适用场景有哪些?

原型模式适用于创建成本高、创建过程复杂或需要隐藏创建细节的对象。一些常见的应用场景包括复杂对象的创建、原型注册表和作为工厂方法模式的替代。

六、原型模式的局限性是什么? \color{red}{六、原型模式的局限性是什么?} 六、原型模式的局限性是什么?

使用原型模式需要注意克隆对象可能包含对其他对象的引用,这可能导致对象图的复制,需要特别小心处理。克隆过程可能会比直接创建对象更复杂,需要对克隆方法进行合理的实现。


八、文末福利

为了回馈粉丝们的大力支持,博主争取到了出版社的活动参与资格,和清华大学出版社一起给粉丝们送书啦!

第一期送给粉丝们的是《Java 从入门到精通(第 7 版)》,Java入门经典,95 万 Java 程序员的入行选择,图书介绍如下。

本书从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细讲解了使用Java语言进行程序开发需要掌握的知识。书中所有知识都结合具体实例进行讲解,涉及的程序代码都给出了详细的注释,这可以帮助读者轻松领会Java程序开发的精髓,并快速提高开发技能。

图书购买链接:京东商城、当当网。

在这里插入图片描述


活动奖励: 《 J a v a 从入门到精通(第 7 版)》 \color{red}{《Java 从入门到精通(第 7 版)》} Java从入门到精通(第7版)》包邮。
参与方式: 点赞 + 收藏 + 评论本博客即可参与 \color{red}{点赞+收藏+评论本博客即可参与} 点赞+收藏+评论本博客即可参与
开奖时间:2023 年 9 月 12 日。
通知方式:CSDN 私信。


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/979124.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python3

#安装python3 brew install python3 看到下图表示安装python3成功: #将python3 加入环境变量 export PATH$PATH:/opt/homebrew/bin/#查看python 版本 python3 --version#查看pip 版本 pip3 --version#更新python源 pip3 config set global.index-url https://pypi.tuna.tsing…

免费电商api接口,分享给你「建议收藏」

API(应用程序编程接口) ​ API(Application Programming Interface,应用程序接口)是一些预先定义的函数,或指软件系统不同组成部分衔接的约定。目的是提供应用程序与开发人员基于某软件或硬件得以访问一组…

高忆管理;三天翻倍!地产“三仙”狂飙

9月6日,一度全部成为“仙股”的三家闻名香港上市房企,融创我国、我国恒大、碧桂园大涨。其间两家已顺利摘掉“仙股”帽子。 截至发稿,融创我国涨20.25%,报1.9港元/股,总市值报104亿港元,不到三个交易日股价…

[LeetCode周赛复盘] 第 361 场周赛20230906

[LeetCode周赛复盘] 第 361 场周赛20230906 一、本周周赛总结2843. 统计对称整数的数目1. 题目描述2. 思路分析3. 代码实现 2844. 生成特殊数字的最少操作1. 题目描述2. 思路分析3. 代码实现 2845. 统计趣味子数组的数目1. 题目描述2. 思路分析3. 代码实现 2846. 边权重均等查…

提升客户体验,你只需要做到这一点

自动回复是指由特定事件或操作触发的自动响应,例如在即时通讯工具上接收消息,它用于通知发件人他们的消息已被收到。不仅可以在WhatsApp,Messenger等渠道上设置自动回复,如果您使用了像SaleSmartly(SS客服)…

任意文件读取及漏洞复现

文章目录 渗透测试漏洞原理任意文件读取1. 任意文件读取概述1.1 漏洞成因1.2 漏洞危害1.3 漏洞分类1.4 任意文件读取1.4.1 文件读取1.4.2 任意文件读取1.4.3 权限问题 1.5 任意文件下载1.5.1 一般情况1.5.2 PHP实现1.5.3 任意文件下载 2. 任意文件读取攻防2.1 路径过滤2.1.1 过…

无需麻烦验证,文字验证码一键通过

前言 文字验证码,简单易用,安全可靠!不需要麻烦的图形识别。这种验证方式不仅方便快捷,而且能有效防止恶意攻击和机器人访问。无需担心复杂操作,只需几秒钟就能完成验证过程。保护您的个人信息和数据安全,…

PG 的状态机和peering过程

首先来解释下什么是pg peering过程? 当最初建立PG之后,那么需要同步这个pg上所有osd中的pg状态。在这个同步状态的过程叫做peering过程。同样当启动osd的时候,这个osd上所有的pg都要进行peering过程,同步pg的状态。peering过程结…

【K 均值聚类】02/5:简介

一、说明 k-mean算法是一种聚类算法,它的主要思想是基于数据点之间的距离进行聚类。K-means聚类是一种无监督的机器学习算法。让我们再解释一下这句话。聚类分析的目标是将数据划分为同类聚类。每个聚类中的点彼此之间比其他聚类中的点更相似。 无监督机器学习是在没…

k8s集群中集群方式安装nacos

1、前提条件 一个k8s集群,其中有三个master 节点,这三个节点的标签名称为etcd 三个master节点的ip 分别为:192.165.187.170 、192.165.187.171、192.165.187.172一个mysql 数据库, 数据库的ip 为:192.165.187.180 用户…

Java虚拟机整型数加载指令学习

JVM中 int 类型数值,根据 取值范围将 入栈的 字节码指令 就分为4类: 取值 -1~5 采用 iconst 指令; 取值 -128~127 采用 bipush 指令; 取值 -32768~32767 采用 sipush指令; 取值 -2147483648~2147483647 采用 ldc 指令。…

pyppeteer模块常用方法

目录 await page.方法 设置相关 setUserAgent(str) setCookie(cookie1, cookie2.......) 页面相关 goto(url) reload() goBack()/goForward() 执行js evaluate(js_str) 截图 screenshot(dict) 保存pdf pdf(dict) 获取内容 content() co…

Fragment的创建分析

之前的文章讨论了Fragment的销毁流程,初始状态为resume,然后经历pause -> stop -> destroyView -> destroy -> detach这么几个流程(本篇文章基于Support27.1.1来分析的)。清楚了Fragment的销毁,那也来看看…

《向量数据库指南》——AI原生向量数据库Milvus Cloud 2.3架构升级

架构升级 GPU 支持 早在 Milvus 1.x 版本,我们就曾经支持过 GPU,但在 2.x 版本中由于切换成了分布式架构,同时出于对于成本方面的考虑,暂时未加入 GPU 支持。在 Milvus 2.0 发布后的一年多时间里,Milvus 社区对 GPU 的呼声越来越高,再加上 NVIDIA 工程师的大力配合——为…

CTFHUB ICS(1)

1.异常的工程文件 把文件拖到kali里面去了 unzip 文件名解压文件 文件很多,我们先进到解压的文件夹里面 strings $(find . | xargs) | grep flag linux命令的作用是在当前目录及子目录下递归查找文件,提取文件中的字符串,然后用grep过滤 find . - 在当前目录及递…

cadence virtuoso bandgap温漂公式

先仿真温漂,然后将曲线send to calculate。 调用ymax,ymin,average函数。

PGInfo核心字段详解

PGInfo存在于PG的整个生命周期中,其在对象数据的写入、数据恢复、PG Peering过程中均发挥重要的作用。本章试图研究pg info在整个PG生命周期中的变化过程,从而对PG及PGInfo有一个更深入的理解。 class PG : DoutPrefixProvider { public:// pg statepg_…

Unable to remove Temporary User Data

错误截图 原因 项目的临时数据目录是存在了未授权的盘符,当删除它的时候,遇到了权限问题,没有权限没法删除。 解决方法 增加字段:userDataDir 解决

WSL使用技巧 / 虚拟机对比

WSL使用技巧 / 虚拟机对比 前言虚拟机比较VMware使用技巧WSL使用技巧官方文档工具安装WSL基本命令运行命令关闭卸载磁盘管理导入导出指定安装路径 前言 本文介绍了VMware和WSL的区别,并详细介绍了WSL的使用方法和技巧。 虚拟机比较 VMware 比较灵活,拥…

高压放大器该如何选择(高压放大器选型要求有哪些)

选择适合的高压放大器对于电子设备和实验中的特定应用非常重要。高压放大器通常用于放大高电压信号,如激光驱动、粒子加速器、电力系统和医学成像等领域。在选择高压放大器时,以下几个因素值得考虑。 首先,您需要确定所需的输出电压范围。不同…