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

探索设计模式:原型模式

设计模式之原型模式

    • 🧐1. 概念
    • 🎯2. 原型模式的作用
    • 📦3. 实现
      • 1. 定义原型接口
      • 2. 定义具体的原型类
      • 3. 定义客户端
      • 4. 结果
    • 📰 4. 应用场景
    • 🔍5. 深拷贝和浅拷贝

在这里插入图片描述

  在面向对象编程中,设计模式是一种通用的解决方案,用于解决软件设计过程中常见的问题。原型模式(Prototype Pattern)作为创建型设计模式的一员,旨在通过复制现有对象来创建新对象,而非通过常规的构造函数。这种模式不仅简化了对象的创建过程,而且在特定情况下还能显著提升性能。

🧐1. 概念


  原型模式允许客户端复制一个已存在的对象,而不是通过常规的构造器创建一个新的实例。这种方法的主要优点在于,如果对象的创建成本很高(例如,初始化过程复杂、需要从数据库加载大量数据等),那么通过复制现有对象的方式可以有效减少资源消耗,提高系统的整体性能。

在这里插入图片描述

  1. Prototype抽象原型类):它是声明克隆方法的接口,是所有具体原型类的公共父类,可以是抽象类也可以是接口,甚至还可以是具体实现类。
  2. ConcretePrototype具体原型类):它实现在抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象。
  3. Client客户端类):通过调用 clone() 方法来创建新的对象,并展示了原始对象与克隆对象之间的独立性。

🎯2. 原型模式的作用

  1. 简化对象创建:通过复制现有的对象,可以避免复杂的构造过程,尤其是当对象的初始化需要进行大量的计算或资源分配时。
  2. 提高性能:对于那些创建成本高得对象,使用原型模式可以显著减少内存消耗和处理时间。
  3. 增加系统灵活性:通过修改原型对象得属性,可以快速生成不同状态的新对象,这比通过继承来实现更加灵活。

📦3. 实现


  实现原型模式的核心在于定义一个原型接口,该接口包含一个用于复制自身的克隆方法。在不同的编程语言中,实现方式可能会有所不同,但基本思路是一致的。

1. 定义原型接口


public interface Prototype extends Cloneable {Prototype clone();
}

此处的 Cloneable 接口是一个标记接口,表示该类可以被克隆。
类似的标记接口还有

  • Serializable:用于标记一个类的对象可以被序列化和反序列化。
  • RandomAccess:用于标记一个列表支持随机访问,即通过索引直接访问元素吗,而不是遍历。
  • Remote:用于远程方法调用,标记一个类支持远程方法调用。

2. 定义具体的原型类


public class ConcretePrototype implements Prototype {private String attribute;public ConcretePrototype(String attribute) {this.attribute = attribute;}@Overridepublic Prototype clone() {try {return (ConcretePrototype) super.clone();} catch (CloneNotSupportedException e) {throw new AssertionError("Cannot clone.", e);}}public String getAttribute() {return attribute;}public void setAttribute(String attribute) {this.attribute = attribute;}}

3. 定义客户端


public class Client {public static void main(String[] args) {ConcretePrototype prototype = new ConcretePrototype("Initial Value");ConcretePrototype clonedPrototype = (ConcretePrototype) prototype.clone();System.out.println("Original Attribute: " + prototype.getAttribute());System.out.println("Cloned Attribute: " + clonedPrototype.getAttribute());clonedPrototype.setAttribute("Modified Value");System.out.println("After Modification:");System.out.println("Original Attribute: " + prototype.getAttribute());System.out.println("Cloned Attribute: " + clonedPrototype.getAttribute());}
}

4. 结果


在这里插入图片描述

  在这个示例中,ConcretePrototype 类实现了 Prototype 接口,并提供了具体的 clone() 方法实现。客户端代码展示了如何通过调用 clone() 方法来创建新的对象,并展示了原始对象与克隆对象之间的独立性。

📰 4. 应用场景


在这里插入图片描述

  1. 对象创建成本高:当对象的创建对象过程非常复杂或耗时,例如需要从网络加载数据、执行复炸的算法等,使用原型模式可以通过复制现有对象来节省时间和资源。
  2. 避免复杂的构造过程:如果对象的创建涉及到复杂的初始化步骤,使用原型模式可以简化这些步骤,通过复制已有对象来快速生成新的对象。
  3. 动态对象创建:在某些情况下,程序需要根据用户的输入或其他条件动态地创建对象。原型模式提供了一种灵活的方式来满足这种需求,无需预先定义所有的对象类型。
  4. 实际项目当中使用原型模式,实现 Cloneable 接口并重写 clone() 方法。或者编写自己的特有的原型类 Prototype ,然后实现 Prototypeclone() 方法。

🔍5. 深拷贝和浅拷贝


  在讨论原型模式时,深拷贝浅拷贝是一个不可忽视的话题。浅拷贝只会复制对象的基本数据类型和其他对象的引用,而不会递归地复制引用对象本身。相反,深拷贝会递归地复制整个对象树,确保新对象与原有对象完全独立。

  在 Java 中, 默认的 clone() 方法实现的是浅拷贝。如果需要实现深拷贝,通常需要手动编写代码来处理对象中的引用类型属性。例如,可以使用序列化和反序列化的方式来实现深拷贝:

public class DeepClonePrototype implements Cloneable, Serializable {private transient String attribute; // 使用 transient 修饰符表示不参与序列化public DeepClonePrototype(String attribute) {this.attribute = attribute;}public String getAttribute() {return this.attribute;}public void setAttribute(String attribute) {this.attribute = attribute;}@Overrideprotected DeepClonePrototype clone() {try {// 使用序列化和反序列化实现深拷贝ByteArrayOutputStream byteOut = new ByteArrayOutputStream();ObjectOutputStream out = new ObjectOutputStream(byteOut);out.writeObject(this);ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());ObjectInputStream in = new ObjectInputStream(byteIn);return (DeepClonePrototype) in.readObject();} catch (IOException | ClassNotFoundException e) {throw new AssertionError("Cannot clone.", e);}}}

相关文章:

探索设计模式:原型模式

设计模式之原型模式 🧐1. 概念🎯2. 原型模式的作用📦3. 实现1. 定义原型接口2. 定义具体的原型类3. 定义客户端4. 结果 📰 4. 应用场景🔍5. 深拷贝和浅拷贝 在面向对象编程中,设计模式是一种通用的解决方案…...

NLP论文速读(EMNLP 2023)|工具增强的思维链推理

论文速读|ChatCoT: Tool-Augmented Chain-of-Thought Reasoning on Chat-based Large Language Models 论文信息: 简介: 本文背景是关于大型语言模型(LLMs)在复杂推理任务中的表现。尽管LLMs在多种评估基准测试中取得了优异的成绩…...

JVM垃圾回收详解.②

空间分配担保 空间分配担保是为了确保在 Minor GC 之前老年代本身还有容纳新生代所有对象的剩余空间。 《深入理解 Java 虚拟机》第三章对于空间分配担保的描述如下: JDK 6 Update 24 之前,在发生 Minor GC 之前,虚拟机必须先检查老年代最大…...

什么是事务,事务有什么特性?

事务的四大特性(ACID) 原子性(Atomicity) 解释:原子性确保事务中的所有操作要么全部完成,要么全部不做。这意味着事务是一个不可分割的工作单元。在数据库中,这通常通过将事务的操作序列作为一个…...

深入解析:如何使用 PyTorch 的 SummaryWriter 进行深度学习训练数据的详细记录与可视化

深入解析:如何使用 PyTorch 的 SummaryWriter 进行深度学习训练数据的详细记录与可视化 为了更全面和详细地解释如何使用 PyTorch 的 SummaryWriter 进行模型训练数据的记录和可视化,我们可以从以下几个方面深入探讨: 初始化 SummaryWriter…...

企业微信中设置回调接口url以及验证 spring boot项目实现

官方文档: 接收消息与事件: 加密解密文档:加解密库下载与返回码 - 文档 - 企业微信开发者中心 下载java样例 加解密库下载与返回码 - 文档 - 企业微信开发者中心 将解压开的代码 ‘将文件夹:qq\weixin\mp\aes的代码作为工具拷…...

电脑超频是什么意思?超频的好处和坏处

嗨,亲爱的小伙伴!你是否曾经听说过电脑超频?在电脑爱好者的圈子里,这个词似乎非常熟悉,但对很多普通用户来说,它可能还是一个神秘而陌生的存在。 今天,我将带你揭开超频的神秘面纱,…...

在 AMD GPU 上构建深度学习推荐模型

Deep Learning Recommendation Models on AMD GPUs — ROCm Blogs 2024 年 6 月 28 日 发布者 Phillip Dang 在这篇博客中,我们将演示如何在支持 ROCm 的 AMD GPU 上使用 PyTorch 构建一个简单的深度学习推荐模型 (DLRM)。 简介 DLRM 位于推荐系统和深度学习的交汇…...

阿里云IIS虚拟主机部署ssl证书

宝塔配置SSL证书用起来是很方便的,只需要在站点里就可以配置好,但是云虚拟主机在管理的时候是没有这个权限的,只提供了简单的域名管理等信息。 此处记录下阿里云(原万网)的IIS虚拟主机如何配置部署SSL证书。 进入虚拟…...

Python运算符列表

运算符 描述 xy&#xff0c;x—y 加、减,“"号可重载为连接符 x*y,x*&#xff0a;y&#xff0c;x/y,x&#xff05;y 相乘、求平方、相除、求余&#xff0c;“*”号可重载为重复&#xff0c;“&#xff05;"号可重载为格式化 <&#xff0c;<&#xff0c;&…...

MFC图形函数学习09——画多边形函数

这里所说的多边形是指在同一平面中由多条边构成的封闭图形&#xff0c;强调封闭二字&#xff0c;否则无法进行颜色填充&#xff0c;多边形包括凸多边形和凹多边形。 一、绘制多边形函数 原型&#xff1a;BOOL Polygon(LPPOINT lpPoints,int nCount); 参数&#x…...

GaussianDreamer: Fast Generation from Text to 3D Gaussians——点云论文阅读(11)

此内容是论文总结&#xff0c;重点看思路&#xff01;&#xff01; 文章概述 本文提出了一种快速从文本生成3D资产的新方法&#xff0c;通过结合3D高斯点表示、3D扩散模型和2D扩散模型的优势&#xff0c;实现了高效生成。该方法利用3D扩散模型生成初始几何&#xff0c;通过噪声…...

k8s篇之控制器类型以及各自的适用场景

1. k8s中控制器介绍 在 Kubernetes 中,控制器(Controller)是集群中用于管理资源的关键组件。 它们的核心作用是确保集群中的资源状态符合用户的期望,并在需要时自动进行调整。 Kubernetes 提供了多种不同类型的控制器,每种控制器都有其独特的功能和应用场景。 2. 常见的…...

Node.js 笔记(一):express路由

代码 建立app.js文件&#xff0c;代码如下&#xff1a; const express require(express) const app express() const port 3002app.get(/,(req,res)>{res.send(hello world!)})app.listen(port,()>{console.log(sever is running on http://localhost:${port}) })问…...

bash笔记

0 $0 是脚本的名称&#xff0c;$# 是传入的参数数量&#xff0c;$1 是第一个参数&#xff0c;$BOOK_ID 是变量BOOK_ID的内容 1 -echo用于在命令窗口输出信息 -$()&#xff1a;是命令替换的语法。$(...) 会执行括号内的命令&#xff0c;并将其输出捕获为一个字符串&#xff…...

mongoDB副本集搭建-docker

MongoDB副本集搭建-docker 注&#xff1a;在进行副本集搭建前&#xff0c;请先将服务部署docker环境并正常运行。 #通过--platform指定下载镜像的系统架构 在这我用的是mongo:4.0.28版本 arm64系统架构的mongo镜像 docker pull --platformlinux/arm64 mongo:4.0.2#查看镜像是…...

Python软体中使用 Flask 或 FastAPI 搭建简单 RESTful API 服务并实现限流功能

Python软体中使用 Flask 或 FastAPI 搭建简单 RESTful API 服务并实现限流功能 引言 在现代 web 开发中,RESTful API 已成为应用程序之间进行通信的标准方式。Python 提供了多种框架来帮助开发者快速搭建 RESTful API 服务,其中 Flask 和 FastAPI 是最受欢迎的两个框架。本…...

CentOS操作系统下安装Nacos

CentOS下安装Nacos 前言 这在Centos下安装配置Nacos 下载Linux版Nacos 首先到Nacos的 Github页面&#xff0c;找到所需要安装的版本 也可以右键复制到链接&#xff0c;然后通过wget命令进行下载 wget https://github.com/alibaba/nacos/releases/download/1.3.2/nacos-ser…...

C++设计模式之适配器模式与桥接模式,装饰器模式及代理模式相似点与不同点

适配器模式、桥接模式、装饰器模式和代理模式在形式上有一些相似之处&#xff0c;因为它们都涉及到对类的功能或接口的修改、增强或转换。然而&#xff0c;它们在动机和目的上有着显著的不同。以下是对这些模式相似点和不同点的清晰说明&#xff1a; 相似点&#xff1a; 结构…...

ThreadLocal 和 Caffeine 缓存是两种不同的缓存机制,它们在用途和实现上有明显的区别

ThreadLocal 和 Caffeine 缓存是两种不同的缓存机制&#xff0c;它们在用途和实现上有明显的区别&#xff1a; ThreadLocal 缓存&#xff1a; ThreadLocal 提供了线程局部变量的功能&#xff0c;每个线程可以访问自己的局部变量&#xff0c;而不会与其他线程冲突。ThreadLocal …...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...

Django RBAC项目后端实战 - 03 DRF权限控制实现

项目背景 在上一篇文章中&#xff0c;我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统&#xff0c;为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...