二十三种设计模式全面解析-原型模式进阶之原型管理器:集中管理对象原型的设计模式之道
在软件开发中,我们经常需要创建和复制对象。然而,有时候直接创建对象可能会导致性能下降或代码重复。为了解决这些问题,原型模式应运而生。而使用原型管理器(Prototype Manager)来集中管理原型对象可以进一步提高灵活性和可维护性。本文将详细介绍原型管理器的用途、与其他设计模式的结合实践,并重点讨论处理深克隆和浅克隆的问题。
一、原型管理器的作用与实践
原型管理器是一个中心化的存储库,用于管理和提供原型对象的克隆副本。它能够集中管理多个原型对象,并提供一种简单的方式来获取和复制这些对象。这种集中化的管理方式带来了以下优点:
- 提高创建对象的效率:通过原型管理器,我们可以在需要时直接克隆原型对象,避免了重复创建对象的开销。
- 简化对象创建过程:原型管理器将创建对象的过程集中在一处,使得创建逻辑更加清晰,代码更易维护。
- 促进对象的复用:原型管理器可以在不同的场景中重复使用原型对象,提高了代码的可扩展性和可维护性。
为了更好地理解原型管理器的实践,让我们结合工厂方法模式和单例模式来演示其用法。
1、创建原型接口和具体原型类
首先,我们定义一个原型接口 Prototype,其中包含 clone 方法用于克隆对象。
public interface Prototype extends Cloneable {Prototype clone();
}
然后,我们创建具体的原型类 ConcretePrototype1 和 ConcretePrototype2,它们实现了 Prototype 接口并重写了 clone 方法。
public class ConcretePrototype1 implements Prototype {@Overridepublic Prototype clone() {try {return (ConcretePrototype1) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}public class ConcretePrototype2 implements Prototype {@Overridepublic Prototype clone() {try {return (ConcretePrototype2) super.clone();} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}
}
2、创建原型管理器
接下来,我们创建原型管理器 PrototypeManager,它负责集中管理原型对象并提供克隆副本。
import java.util.HashMap;
import java.util.Map;public class PrototypeManager {private static Map<String, Prototype> prototypes = new HashMap<>();public static void registerPrototype(String key, Prototype prototype) {prototypes.put(key, prototype);}public static Prototype clonePrototype(String key) {Prototype prototype = prototypes.get(key);if (prototype != null) {return prototype.clone();}return null;}
}
在上述代码中,PrototypeManager 使用一个 Map 数据结构来存储原型对象,其中键是对象的标识符,值是原型对象本身。
registerPrototype 方法用于注册原型对象,将其添加到管理器中。
clonePrototype 方法根据指定的键来获取对应的原型对象,并通过克隆方法创建并返回一个克隆副本。
3、使用原型管理器和其他设计模式的实践
原型管理器与其他设计模式的结合使用可以增强系统的灵活性和可扩展性。
下面以工厂方法模式和单例模式为例,演示如何结合这些模式来使用原型管理器。
首先,我们创建一个工厂类 ProductFactory,它使用原型管理器来创建产品对象。
public class ProductFactory {public static Product createProduct(String type) {Prototype prototype = PrototypeManager.clonePrototype(type);if (prototype instanceof Product) {return (Product) prototype;}return null;}
}
在上述代码中,ProductFactory 中的 createProduct 方法根据传入的类型(键),通过原型管理器获取对应的原型对象,并将其转换为产品对象。
接下来,我们创建一个单例类 Application,它使用工厂方法来创建产品对象。
public class Application {private static Application instance = new Application();private Application() {}public static Application getInstance() {return instance;}public void run() {Product product = ProductFactory.createProduct("Type1");if (product != null) {product.doSomething();}}
}
在上述代码中,Application 是一个单例类,通过 getInstance 方法获取唯一的实例。在 run 方法中,我们使用工厂方法创建产品对象,并调用其方法。
二、处理深克隆和浅克隆的问题
在使用原型模式时,我们常常需要考虑克隆对象的属性类型。默认情况下,克隆操作是浅克隆,即只复制基本类型的属性值,而引用类型的属性仍然指向相同的对象。这可能导致在修改克隆对象时,原对象的引用类型属性也会受到影响。
为了解决这个问题,我们可以在具体原型类中进行深克隆的处理。深克隆会复制引用类型属性所指向的对象,从而确保克隆对象和原对象的引用类型属性指向不同的对象。
下面是一个修改后的代码示例,展示了如何处理深克隆和浅克隆的问题:
public class ConcretePrototype1 implements Prototype {private String name;private List<String> list;public ConcretePrototype1(String name, List<String> list) {this.name = name;this.list = list;}// 深克隆@Overridepublic Prototype clone() {try {ConcretePrototype1 clone = (ConcretePrototype1) super.clone();clone.list = new ArrayList<>(list); // 创建新的列表对象并复制原列表的元素return clone;} catch (CloneNotSupportedException e) {e.printStackTrace();return null;}}// 省略其他方法和属性
}
在上述代码中,ConcretePrototype1 类中添加了一个名为 list 的引用类型属性,并在 clone 方法中进行了深克隆。
总结:
原型管理器是一种有助于集中管理对象原型的设计模式,它能够提高对象创建的效率和代码的可维护性。通过与其他设计模式的结合实践,如工厂方法模式和单例模式,我们可以进一步增强系统的灵活性和可扩展性。
同时,在处理深克隆和浅克隆的问题时,我们需要根据具体需求选择合适的克隆方式,并在具体原型类中进行相应的处理。深克隆和浅克隆的选择将影响对象属性的独立性和引用对象的共享性。
通过本文的介绍,相信你对原型管理器的概念和使用有了更深入的了解。在实际开发中,原型管理器可以帮助我们更好地管理对象原型,并提高代码的效率和可维护性。
然而,设计模式世界中还有许多其他精彩的故事等待我们探索。在下一篇博文中,我们将深入研究另一个引人入胜的设计模式,为你带来更多惊喜。敬请期待!
好了,今天的分享到此结束。如果觉得我的博文帮到了您,您的点赞和关注是对我最大的支持。如遇到什么问题,可评论区留言。
相关文章:
二十三种设计模式全面解析-原型模式进阶之原型管理器:集中管理对象原型的设计模式之道
在软件开发中,我们经常需要创建和复制对象。然而,有时候直接创建对象可能会导致性能下降或代码重复。为了解决这些问题,原型模式应运而生。而使用原型管理器(Prototype Manager)来集中管理原型对象可以进一步提高灵活性…...
【微信小程序开发】学习小程序的网络请求和数据处理
前言 网络请求是微信小程序中获取数据和与服务器交互的重要方式。微信小程序提供了自己的API来处理网络请求,使得开发者可以轻松地在微信小程序中实现数据的获取和提交。本文将介绍微信小程序中的网络请求,包括使用wx.request发起GET和POST请求…...
微信小程序 slot 不显示
问题:创建组件,使用带名字的slot,页面调用组件使用slot不显示 源码: 组件xml <view class"p-item br24" style"{{style}}"><slot name"right" wx:if"{{!custBottom}}"></slot>&l…...
Spring Boot 优雅配置yml配置文件定义集合、数组和Map
一、value 获取配置文件 在平时的yml配置文件中,我们经常使用到配置基本数据类型的字符串,比如配置日志文件的写法如下: # 配置日志输出级别 logging:# 指定logback配置文件的位置 config: classpath:logback-spring.xml# 文件日志要输出的路…...
java+springboot+vue开发的大学生健康检测小程序
主要功能测试身体健康指数,添加病历,添加日历清单等,管理员导出学生健康电子档案表等。前端小城程序,后端管理员vue开发,接口Java springboot开发。 小程序演示视频 https://www.bilibili.com/video/BV1Kc411d7bb/?s…...
从零开始的LINUX(四)
1.yum: 功能:软件包管理器,功能类似与手机上的应用商店。通过yum可以获取指令的下载地址,然后一键式安装指令。由于yum中的地址一般都是外网的,所以需要镜像源(即国内的下载地址)。 相关指令&…...
组播应用层收不到问题-接收网卡绑定
问题背景: 平台:Android 设备A:组播发送者,发送组播数据 设备B:组播接受者,接收组播数据 设备A与设备B通过有线连接,连接在设备B的eth0网卡上 问题: 设备B在没有通讯模块网卡的情况…...
回流重绘零负担,网页加载快如闪电
🎬 江城开朗的豌豆:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️ 生活的理想,就是为了理想的生活 ! 目录 ⭐ 专栏简介 📘 文章引言 一、回…...
QT5.15在Ubuntu22.04上编译流程
在我们日常遇到的很多第三方软件中,有部分软件针对开发人员,并不提供预编译成果物,而是需要开发人员自行编译,此类问题有时候不是问题(编译步骤的doc详细且清晰时),但有时候又很棘手(…...
【电路笔记】-交流波形和交流电路理论
交流波形和交流电路理论 文章目录 交流波形和交流电路理论1、概述2、交流发电2.1 涡轮发电2.2 变压器 3、交流功率3.1 RMS值3.2 功率分配 4、总结 当谈论电流或电压时,这些信号可以分为两大类:直流和交流。 DC 状态为“直流电”,该定义重新组…...
vue2 系列:自定义 v-model
1. input 中的 v-model <!-- 表单双向绑定 --> <input :value"username" input"username $event.target.value" /> <!-- 等于 --> <input v-model"username" /> 2. 自定义组件 v-model <!-- 组件双向绑定 -->…...
广东木模板批发,建筑桥梁工程专用组合木模板
作为广东地区的木模板批发商,我们致力于为建筑行业提供高品质的木模板产品。在众多产品中,我们特别推荐我们的建筑桥梁工程专用组合木模板,为桥梁工程提供卓越的支持和出色的性能。 我们的组合木模板是专为桥梁工程设计的,以满足对…...
工业相机常见的工作模式、触发方式
参考:机器视觉——工业相机的触发应用(1) - 知乎 工业相机常见的工作模式一般分为: 触发模式连续模式同步模式授时同步模式 触发模式:相机收到外部的触发命令后,开始按照约定时长进行曝光,曝光结束后输出一帧图像。…...
【C语言】指针那些事(上)
C语言系列 文章目录 文章目录 一. 字符指针 一.(1 ) 数组创建空间的地址和指针指向的地址 二. 指针数组 二.(1)指针数组模拟一个二维数组 三. 数组指针 三.(1)数组指针到底有什么用 对一维数组没有什么用 二.(…...
liunx Centos-7.5上 rabbitmq安装
在安装rabbitmq中需要注意: 1、rabbitmq依赖于erlang,需要先安装erlang 2、erlang和rabbitmq版本有对应关系 可参考网页:https://www.rabbitmq.com/which-erlang.html 第一步,安装编译工具及库文件,如果服务器上已经有了&…...
蓝桥杯学长经验笔记
平台:立扣,牛客网,蓝桥云课 ,codeforce刷题时间:刷题时间: 每天:有课一个多小时 周末 3-4 小时:学一部分做一点题书:《算法竞赛从入门到进阶》、《算法笔记》、《算法竞赛…...
开发库介绍
一、开发库选择 1.1 概述 STM32开发相关的库有很多,它们都是为了方便开发者使用STM32微控制器而提供的软件工具。根据不同的功能和层次,可以将它们分为以下几类: CMSIS库(Cortex Microcontroller Software Interface Standard&am…...
基于单片机的智能清洁小车设计—控制系统设计
收藏和点赞,您的关注是我创作的动力 文章目录 概要 一、研究的主要内容和目标二、总体方案设计2.1智能清洁小车的硬件系统组成2.2智能清洁小车的硬件结构图 三、 小车结构设计5.1基本布局和功能分析5.2小车二维及三维图小车三维图: 四、 原理图程序 五、…...
玩转视图变量,轻松实现动态可视化数据分析
前言 在当今数据驱动的世界中,数据分析已经成为了企业和组织中不可或缺的一部分。传统的静态数据分析方法往往无法满足快速变化的业务需求和实时决策的要求。为了更好地应对这些挑战,观测云的动态可视化数据分析应运而生。 在动态可视化数据分析中&…...
【51单片机】:智能施工电梯系统
项目效果: 基于51单片机的智能施工电梯系统 摘 要 智能施工电梯系统目前广泛应用于人们建筑工程中,为人们施工时上下搬运提供了极大的便利。智能施工电梯系统包括密码开启、超重提示,电梯运作及相关信息显示等等功能,施工电梯为我…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
用js实现常见排序算法
以下是几种常见排序算法的 JS实现,包括选择排序、冒泡排序、插入排序、快速排序和归并排序,以及每种算法的特点和复杂度分析 1. 选择排序(Selection Sort) 核心思想:每次从未排序部分选择最小元素,与未排…...
中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点
中科院1区顶刊|IF14:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点 当下,免疫与代谢性疾病的关联研究已成为生命科学领域的前沿热点。随着研究的深入,我们愈发清晰地认识到免疫系统与代谢系统之间存在着极为复…...
AWSLambda之设置时区
目标 希望Lambda运行的时区是东八区。 解决 只需要设置lambda的环境变量TZ为东八区时区即可,即Asia/Shanghai。 参考 使用 Lambda 环境变量...
