设计模式(创建型)- 原型模式

目录

定义

类图

角色

优缺点

优点

缺点

应用场景

案例展示

浅克隆

深克隆


定义

        原型模式旨在创建重复的对象,同时确保良好的性能表现。它通过复制现有对象(原型)来创建新对象,而非使用传统的构造函数创建方式。这种设计模式属于创建型模式,为对象创建提供了一条便捷、高效的途径。其核心在于,通过复制原型对象的属性和状态,极大地减少了新对象创建过程中的资源消耗和时间成本。

类图

角色

  1. 原型(Prototype):声明一个克隆自身的接口,这是所有支持克隆操作的类的通用接口。它为具体原型类定义了克隆方法的规范,使得具体原型类只需实现该接口,就能实现对象的克隆。​

  2. 具体原型(Concrete Prototype):实现原型接口,定义克隆方法。在克隆方法中,具体原型类会创建一个与自身属性和状态相同的新对象,并返回该对象。

优缺点

优点

  • 性能优势:Java 自带的原型模式基于内存二进制流的复制,相比直接使用new关键字创建对象,能显著提升性能。在创建复杂对象时,new操作需要经历类的加载、初始化等一系列过程,而原型模式通过复制内存中的对象,避免了这些繁琐的步骤,大幅缩短了对象创建的时间。​

  • 状态保存与恢复:借助深克隆,原型模式可以完整地保存对象的状态。这一特性在实现撤销操作或恢复对象历史状态时极为有用。通过克隆并保存对象的特定状态,程序能够在需要时轻松恢复到之前的状态,简化了状态管理的复杂度。

缺点

  • 违背开闭原则:由于clone方法位于类的内部,对已有类进行改造以支持原型模式时,需要修改类的代码。这与开闭原则相悖,可能导致代码的可维护性降低,尤其是在大型项目中,牵一发而动全身,增加了系统的维护成本。​

  • 深克隆实现复杂:在实现深克隆时,需要编写复杂的代码。当对象之间存在多重嵌套引用时,为了确保所有层次的对象都能被正确克隆,每个层次的对象对应的类都必须支持深克隆,这无疑增加了实现的难度和复杂性。

应用场景

  • 对象相似性高:当系统中需要创建多个相似对象,仅个别属性不同时,原型模式是理想的选择。以游戏开发为例,游戏中的角色通常具有相似的基本属性和行为,使用原型模式可以通过克隆一个基础角色,然后修改特定属性,快速创建多个不同的角色实例。​

  • 创建成本高昂:在创建对象成本较大的情况下,如初始化时间长、占用大量 CPU 资源或网络资源,原型模式可以优化资源使用。比如,创建一个需要从数据库加载大量数据并进行复杂计算的对象,通过克隆已有的对象,可以避免重复的加载和计算过程,提高系统的响应速度。​

  • 数据准备繁琐:当创建对象需要繁琐的数据准备或特定的访问权限时,原型模式可以简化对象的创建过程,提高性能和安全性。例如,创建一个需要经过多层权限验证和复杂数据配置的对象,通过克隆已有的合法对象,可以减少不必要的验证和配置步骤。​

  • 大量对象需重新赋值:在系统中大量使用某类对象,且每个调用者都需要为其属性重新赋值的场景下,原型模式可以通过克隆对象,快速满足不同调用者的需求,减少重复创建对象的开销。

案例展示

浅克隆

  • 浅克隆是使用默认的 clone()方法来实现

  • 基本数据类型的成员变量,浅克隆会直接进行值传递(复制属性值给新对象)

  • 引用数据类型的成员变量,浅克隆会进行引用传递(复制引用值(内存地址)给新对象)

  • 在原先Sheep 类基础上实现 Cloneable 接口,重写 clone 方法。


public class Sheep implements Cloneable{private String name;private int age;@Overrideprotected Object clone()  {//克隆该实例,使用默认的clone方法来完成Sheep sheep = null;try {sheep = (Sheep)super.clone();} catch (Exception e) {System.out.println(e.getMessage());}return sheep;}public Sheep(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Sheep{" +"name='" + name + '\'' +", age=" + age +'}';}
}

深克隆

  • 方法1:

    • 引用对象也实现 Cloneable 接口

    • 对象调用引用对象的clone 方法

  • 方法2:

    • 实现序列化接口,不必实现Cloneable 接口了


public class Sheep implements Serializable { //实现序列化接口private String name;private int age;public Cow friend;public Sheep(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Sheep{" +"name='" + name + '\'' +", age=" + age +'}';}public Object deepClone() { //深拷贝//创建流对象ByteArrayOutputStream bos = null;ObjectOutputStream oos = null;ByteArrayInputStream bis = null;ObjectInputStream ois = null;try {//序列化bos = new ByteArrayOutputStream();oos = new ObjectOutputStream(bos);oos.writeObject(this); //当前这个对象以对象流的方式输出//反序列化bis = new ByteArrayInputStream(bos.toByteArray());ois = new ObjectInputStream(bis);Sheep sheep = (Sheep) ois.readObject();return sheep;} catch (Exception e) {e.printStackTrace();return null;} finally {//关闭流try {bos.close();oos.close();bis.close();ois.close();} catch (Exception e2) {System.out.println(e2.getMessage());}}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MQ的数据一致性,如何保证?

1 数据一致性问题的原因 这些年在Kafka、RabbitMQ、RocketMQ踩过的坑,总结成四类致命原因: 生产者悲剧:消息成功进Broker,却没写入磁盘就断电。消费者悲剧:消息消费成功,但业务执行失败。轮盘赌局&#x…

Angular由一个bug说起之十五:自定义基于Overlay的Tooltip

背景 工具提示(tooltip)是一个常见的 UI 组件,用于在用户与页面元素交互时提供额外的信息。由于angular/material/tooltip的matTooltip只能显示纯文本,所以我们可以通过自定义Directive来实现一个灵活且功能丰富的tooltip Overlay…

简单介绍一下Unity中的ScriptableObject

ScriptableObject的本质 ScriptableObject是Unity引擎中的一个特殊基类,允许你创建不依附于游戏对象的数据容器,以资产(Asset)形式存储在项目中。这些资产: 可在编辑器中创建和配置 在构建后作为资产打包 可通过Resources或AssetBundle加…

ubuntu24.04.2 NVIDIA GeForce RTX 4060笔记本安装驱动

https://www.nvidia.cn/drivers/details/242281/ 上面是下载地址 sudo chmod x NVIDIA-Linux-x86_64-570.133.07.run # 赋予执行权限把下载的驱动复制到家目录下,基本工具准备,如下 sudo apt update sudo apt install build-essential libglvnd-dev …

LabVIEW 布尔控件回车键触发程序退出

在 LabVIEW 开发过程中,部分用户可能会遇到按下回车键(Enter)后,程序意外退出的问题。该问题主要源于布尔控件的属性设置冲突,包括键分配、数据绑定及 Tab 键行为等。本文将详细分析问题根源,并提供一套完整…

分布式系统面试总结:3、分布式锁(和本地锁的区别、特点、常见实现方案)

仅供自学回顾使用,请支持javaGuide原版书籍。 本篇文章涉及到的分布式锁,在本人其他文章中也有涉及。 《JUC:三、两阶段终止模式、死锁的jconsole检测、乐观锁(版本号机制CAS实现)悲观锁》:https://blog.…

WebWorkers在项目中的使用案例

Worker | 文档 worker 线程的关闭在主线程和 worker 线程都能进行操作,但对 worker 线程的影响略有不同。 // main.js(主线程) const myWorker new Worker(/worker.js); // 创建worker myWorker.terminate(); // 关闭worker 复制代码 // wor…

vue ts+Windi CSS

1、创建vue项目 trae(字节)打开一个空文件夹 npm install -g vue/cli vue create my-project cd my-project vue add typescript npm run serve vue项目创建完成 2、安装windicss vue add windicss vue.config.js配置 npm install vue-router …

【HTML 基础教程】HTML 编辑器

HTML 编辑器推荐 可以使用专业的 HTML 编辑器来编辑 HTML,菜鸟教程为大家推荐几款常用的编辑器: VS Code:Visual Studio Code - Code Editing. RedefinedSublime Text:http://www.sublimetext.com/在线编辑器:HTML/C…

文件上传的小点总结(2)

4.黑名单绕过(.htaccess方法) 源码一打开,遇到这样的黑名单是不是看的头皮发麻,这么多后缀都禁用。 .htaccess可以启用或禁用apache的功能,利用这个特点,我们可以使用该文件来禁用上述黑名单功能,从而上传**文件。 简…

mysql--主从复制--部署

MySQL 主从复制部署教程 一、主节点(Master)配置 1. 创建目录结构 mkdir -p /usr/local/src/mysql_demo/master_replica/{logs,configFile,data}2. 编写主节点的 MySQL 配置文件 my.cnf 路径:/usr/local/src/mysql_demo/master_replica/co…

Qt弹出新窗口并关闭(一个按钮)

参考:Qt基础 练习:弹出新窗口并关闭的两种实现方式(两个按钮、一个按钮)_qt打开一个窗口另一个关闭-CSDN博客 实现: 一个按钮,点击一次,按钮的名字从open window变为close window,…

游戏引擎学习第185天

回顾并计划今天的内容 我们完成了开始整理这些数据的工作,但我们还没有机会真正去查看这些数据的具体内容,因为我们只是刚刚开始了数据整理的基本工作。我们收集了大量的信息,但到目前为止,仍然没有足够的可视化工具来帮助我们理…

《一本书讲透Elasticsearch:原理、进阶与工程实践》读书笔记

1:es的组成部分: Elasticsearch 引擎:核心组件,处理索引和搜索请求 Kibana:es的可视化的数据界面,用于分析和展示数据 Beats(可选)轻量级的日志采集器 2:基本概念 es开…

[React 进阶系列] 组合组件 复合组件

[React 进阶系列] 组合组件 & 复合组件 今天写个人项目练手的时候搜到了一个比价有趣的实现,于是用了一下,发现这个 concept 不是特别的熟,于是上网找了下,返现了一个叫 复合组件(compound components) 的概念。搜索了一下后…

HarmonyOS NEXT 鸿蒙中关系型数据库@ohos.data.relationalStore API 9+

核心API ohos.data.relationalStore API 9 数据库 数据库是存储和管理数据的系统 数据库(Database)是一个以特定方式组织、存储和管理数据的集合,通常用于支持各种应用程序和系统的运行。它不仅是存放数据的仓库,还通过一定的…

用HTML和CSS生成炫光动画卡片

这个效果结合了渐变、旋转和悬浮效果的炫酷动画示例&#xff0c;使用HTML和CSS实现。 一、效果 二、实现 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&quo…

蓝桥杯第10届 后缀表达式

题目描述 给定 N 个加号、M 个减号以及 NM1 个整数 A1,A2,⋅⋅⋅,ANM1​&#xff0c;小明想知道在所有由这N 个加号、M 个减号以及 NM1 个整数凑出的合法的 后缀表达式中&#xff0c;结果最大的是哪一个&#xff1f; 请你输出这个最大的结果。 例如使用 1 2 3 -&#xff0c…

常见框架漏洞攻略-ThinkPHP篇

漏洞名称&#xff1a;Thinkphp5x远程命令执行及getshell 第一步&#xff1a;开启靶场 第二步&#xff1a;准备工具 第三步&#xff1a;启动工具&#xff0c;进行漏洞检测 #存在漏洞 1.目标存在tp5_invoke_func_code_exec_1漏洞2.目标存在tp5_dbinfo_leak漏洞payload:http://47…

sql长时间卡在gc current request事件

问题描述 凌晨跑批出现超时。SQL f0ng33agbpzhs业务需要执行160w次左右。现场人员杀掉该sql&#xff0c;重新发起业务&#xff0c;业务批次成功跑完。 问题分析 总体sql分析 分析对比sql的awrsqrpt&#xff0c;对比昨天3月8日的。 总体执行次数没有变化。Cpu时间、物理读等均…