设计模式-注册模式
- 模式介绍
- 模式特点
- 应用场景
- 注册模式和单例模式的区别
- 代码示例
- Java实现注册模式
- Python实现注册模式
- 注册模式在spring中的应用
模式介绍
注册模式是一种设计模式,也称为注册树或注册器模式。这种模式将类的实例化和创建分离开来,避免在应用程序启动时实例化对象,以避免造成资源的浪费。
注册模式的核心思想是将类的创建和管理的代码封装到一个工厂类中,用户代码无需显式地通过“new”关键字实例化对象。相反,用户可以将类对象注册到全局的注册树上,这些对象就可以被应用程序中的任何地方访问。
使用注册模式的优势在于,它提供了一种集中管理对象的方式,避免了在每个需要使用对象的地方重复创建和销毁对象。此外,通过将对象的创建和销毁逻辑集中管理,可以更好地控制对象的生命周期,减少内存泄漏和性能问题。
此外,注册模式还可以与其他设计模式结合使用,例如与单例模式和工厂模式结合,以实现更加灵活和可扩展的对象创建和管理方式。

模式特点
- 注册模式的优点包括:
- 集中管理 :注册模式将对象的创建和管理集中到一个地方,方便对对象进行统一管理和维护。
- 避免重复创建 :通过将对象注册到全局的注册树上,避免了在每个需要使用对象的地方重复创建和销毁对象,减少了资源浪费。
- 灵活扩展 :注册模式提供了注册和注销接口,方便用户动态添加或删除对象,使得应用程序更加灵活和可扩展。
- 注册模式也存在一些缺点:
- 依赖管理 :注册模式需要管理对象的生命周期,因此需要谨慎处理对象的创建和销毁,避免出现内存泄漏等问题。
- 注册配置 :使用注册模式需要对每个对象进行注册配置,增加了开发的工作量。
- 性能开销 :虽然注册模式避免了重复创建对象,但在某些情况下,对象的创建和销毁仍然需要一定的性能开销。
因此,在使用注册模式时,需要根据实际情况进行权衡,并谨慎处理对象的生命周期和依赖关系。

应用场景
注册模式在以下场景中可能会得到应用:
- 插件扩展开发:在应用程序中,通常会有一些固定的功能模块,而插件可以在这些功能模块的基础上进行扩展,为应用程序提供更多的功能。通过注册模式,可以将应用程序中的各个功能模块、插件统一管理,从而提高应用程序的可维护性和扩展性。
- 模块化的程序设计:通过注册模式,开发者可以将应用程序中的各个模块、子系统相互依赖,从而进行模块化的程序设计。
- 跨集群注册发现:在多容器集群环境下,需要选择主备或者双活/多活模式,采用全容器注册或部署独立的注册发现中心,或者单一注册发现中心或每个集群都附属自己的注册发现中心,或者分层注册机制等。这种场景下,注册模式可以提供持续稳定的注册发现服务。
- API Gateway层API注册机制:API网关层提供API的注册,通过APIPortal提供API集市,通常适合有OpenAPI需求的场景,安全性方面要求相对比较高。
请注意,这些只是注册模式可能的应用场景,具体是否适用需要根据项目的具体需求和上下文来判断。

注册模式和单例模式的区别
注册模式和单例模式是两种不同的设计模式,它们的主要区别在于实现方式和应用场景。
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。单例模式通常用于创建系统中只需要一个实例的类,例如日志记录器、配置管理器等。单例模式通过在类中实现一个私有静态实例,并在类中提供公共静态方法来获取该实例,从而实现全局访问点。
注册模式是一种结构型设计模式,它提供了一种将对象创建和使用分离的方式。注册模式通过将对象注册到全局的注册表中,使得应用程序中的任何地方都可以通过注册表来获取和使用对象。注册模式通常用于创建可配置、可扩展的系统,例如插件系统、服务注册和发现等。
总的来说,单例模式关注的是如何创建唯一的实例,并提供全局访问点;而注册模式关注的是如何管理对象的创建和使用,提供一种灵活、可扩展的对象创建和使用方式。

代码示例
Java实现注册模式
以下是一个简单的Java示例,展示了如何实现注册模式:
import java.util.HashMap;
import java.util.Map;interface Service {void execute();
}class ConcreteServiceA implements Service {public void execute() {System.out.println("ConcreteServiceA is executing.");}
}class ConcreteServiceB implements Service {public void execute() {System.out.println("ConcreteServiceB is executing.");}
}class Registry {private Map<String, Service> services = new HashMap<>();public void registerService(String name, Service service) {services.put(name, service);}public Service getService(String name) {return services.get(name);}
}public class RegistrationPatternDemo {public static void main(String[] args) {Registry registry = new Registry();registry.registerService("serviceA", new ConcreteServiceA());registry.registerService("serviceB", new ConcreteServiceB());Service serviceA = registry.getService("serviceA");serviceA.execute(); // 输出: ConcreteServiceA is executing.Service serviceB = registry.getService("serviceB");serviceB.execute(); // 输出: ConcreteServiceB is executing.}
}
在这个示例中,我们定义了一个Service接口,以及两个实现了该接口的类ConcreteServiceA和ConcreteServiceB。我们还定义了一个Registry类,它使用一个Map来存储注册的服务。registerService方法用于注册服务,而getService方法用于根据名称获取服务。在main方法中,我们创建了一个Registry实例,注册了两个服务,并分别获取和执行它们。
Python实现注册模式
以下是一个Python实现注册模式的示例:
from abc import ABC, abstractmethod
from collections import defaultdictclass Service(ABC):@abstractmethoddef execute(self):passclass ConcreteServiceA(Service):def execute(self):print("ConcreteServiceA is executing.")class ConcreteServiceB(Service):def execute(self):print("ConcreteServiceB is executing.")class Registry:def __init__(self):self.services = defaultdict(list)def register_service(self, name, service):self.services[name].append(service)def get_service(self, name):return self.services.get(name, [])[0] if self.services.get(name) else None# 创建注册器实例
registry = Registry()# 注册服务
registry.register_service("serviceA", ConcreteServiceA())
registry.register_service("serviceB", ConcreteServiceB())# 获取并执行服务
serviceA = registry.get_service("serviceA")
serviceA.execute() # 输出: ConcreteServiceA is executing.serviceB = registry.get_service("serviceB")
serviceB.execute() # 输出: ConcreteServiceB is executing.
在这个示例中,我们定义了一个抽象基类Service,它包含一个抽象方法execute。然后,我们创建了两个实现了Service接口的类ConcreteServiceA和ConcreteServiceB。接下来,我们定义了一个Registry类,它使用一个字典来存储注册的服务。register_service方法用于注册服务,它将服务添加到字典中指定名称的列表中。get_service方法用于根据名称获取服务,它返回第一个注册的服务实例。在示例中,我们创建了一个Registry实例,注册了两个服务,并分别获取和执行它们。

注册模式在spring中的应用
Spring框架中使用了注册模式,主要是通过Spring的ApplicationContext来管理Bean。
Spring的ApplicationContext是一个接口,它实现了注册模式。在Spring中,Bean的创建和管理是通过ApplicationContext来完成的。当应用程序启动时,Spring会创建一个ApplicationContext实例,并将所有注册的Bean加载到该实例中。通过ApplicationContext,我们可以获取和操作这些Bean。
在Spring中,Bean的注册方式有多种,可以通过XML配置文件、注解或者JavaConfig类来实现。通过这些方式,我们可以将Bean定义并注册到Spring的容器中,并由Spring自动管理它们的生命周期和依赖关系。
在Spring中,注册模式的主要应用场景是解耦和模块化。通过将Bean注册到Spring容器中,我们可以将应用程序的不同模块解耦,使得它们之间相互独立,降低了代码的耦合度。同时,通过注册模式,我们可以实现插件化开发,使得应用程序可以根据需要动态添加或删除功能模块。
总之,Spring中的注册模式使得应用程序更加灵活、可扩展和可维护。

设计模式-迭代器模式
设计模式-责任链模式
设计模式-门面模式
相关文章:
设计模式-注册模式
设计模式专栏 模式介绍模式特点应用场景注册模式和单例模式的区别代码示例Java实现注册模式Python实现注册模式 注册模式在spring中的应用 模式介绍 注册模式是一种设计模式,也称为注册树或注册器模式。这种模式将类的实例化和创建分离开来,避免在应用程…...
css 美化滚动条样式
ChatgGPT4.0国内站点: 海鲸AI-支持GPT(3.5/4.0),文件分析,AI绘图 在CSS中,你可以使用伪元素::-webkit-scrollbar以及相关的伪元素来为Webkit浏览器(如Chrome和Safari)自定义滚动条的样式。以下是一些基本的CSS规则&am…...
视频压缩不影响画质简单方法,一分钟搞定!
很多朋友在处理视频的时候都会遇到视频过大的问题,想要压缩视频的同时不影响画质,简单的方法有两种。一种是用专业的压缩软件,在压缩的时候设置一个合适的压缩比例,压缩大小的同时保持清晰度,也能提高压缩率࿰…...
Zookeeper的使用场景
统一命名服务 利用ZooKeeper节点的树形分层结构和子节点的顺序维护能力,来为分布式系统中的资源命名。 例:分布式节点命名 分布式消息队列 1.在Zookeeper中创建一个持久节点,用作队列的根节点。队列元素的节点放在这个根节点下。 2.入队:…...
Java 面试题集锦记录
Java 面试题集锦记录 一1. SpringBoot、SpringCloud区别2. SpringCloud怎么保证服务间通信?3. Spring怎么保持高可用性、稳定性?4. 负载均衡5. [Rabbitmq](https://blog.csdn.net/qq_40985985/article/details/128013229) 怎么避免重复消费,[…...
【自然语言处理】第2部分:识别文本中的个人身份信息
自我介绍 做一个简单介绍,酒架年近48 ,有20多年IT工作经历,目前在一家500强做企业架构.因为工作需要,另外也因为兴趣涉猎比较广,为了自己学习建立了三个博客,分别是【全球IT瞭望】,【…...
C#中的.NET与.NET Framework区别
C#是一种编程语言,而.NET是一个开发平台。在.NET生态系统中,有两个相关但不同的概念:.NET和.NET Framework。 .NET Framework 发布时间: .NET Framework是最早引入的,它于2002年首次发布。它是一个用于构建Windows应…...
详解Keras3.0 Layer API: LSTM layer
LSTM layer 用于实现长短时记忆网络,它的主要作用是对序列数据进行建模和预测。 遗忘门(Forget Gate):根据当前输入和上一个时间步的隐藏状态,计算遗忘门的值。遗忘门的作用是控制哪些信息应该被遗忘,哪些…...
Vue和React的运行时,校验引入包的上下文差异
背景 系统使用 webpack 5 模块联邦实现微前端,有关如何实现跨应用的代码共享,可参考 如何优雅的实现跨应用的代码共享 里的第三大点。 总之,这里是其他应用使用了某个应用共享出来的reg文件,引入方式为: import REG …...
C语言中函数调用和嵌套
函数是C语言的基本组成元素 函数调用 根据函数在程序中出现的位置有下列三种函数调用方式: 将函数作为表达式调用 将函数作为表达式调用时,函数的返回值参与表达式的运算,此时要求函数必须有返回值 int retmax(100,150); 将函数作为语句…...
JVM基础篇---02
为什么需要用户自定义类加载器: 扩展类加载器的功能: Java的默认类加载器主要有三个,分别是引导类加载器、扩展类加载器和应用程序类加载器。其中,引导类加载器和扩展类加载器是由JVM实现的,用户无法修改其行为。而应用…...
HTML网站基础
一、前端开发基础 前端一共三门语言——HTML、CSS、JS(Java Script) HTML用于静态网页框架,CSS用于修饰,JS构成动态网页 1、HTML 对于中文网页需要使用 <meta charset"utf-8"> 声明编码,否则会出现…...
最优化考试之惩罚函数外点法
最优化考试之惩罚函数外点法 一、外点法1.问题条件2.解题过程 一、外点法 1.问题条件 目标函数 f ( x ) f(x) f(x)约束函数 g ( x ) g(x) g(x) 2.解题过程 定义罚函数 F ( x ) f ( x ) t ∗ m i n ( 0 , g ( x ) 2 ) F(x)f(x)t*min(0,g(x)^2) F(x)f(x)t∗min(0,g(x)2)对罚…...
JavaScript 数组【详解】
Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍JavaScript中数组详解 数组声明/基础操作以及部分理论知识 🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁 🍉博主收将持续更新学习记录获,友友们有任何问题可…...
Node.js版本对比
目录 1. node版本与Npm版本对照表 2. node版本与node-sass版本对照表 3. node-sass与sass-loader版本对照表 1. node版本与Npm版本对照表 以往的版本 | Node.js 下面显示最新的对应内容,如果需要查找历史版本,可以进入上面的页面查询 VersionLTSDateV8np…...
人工智能:网络犯罪分子的驱动力
随着 2024 年的临近,是时候展望今年的网络安全状况了。由于网络犯罪日益复杂,预计到 2025 年,全球网络安全成本将增至 10.5 万亿美元。 人工智能的使用不断发展,网络犯罪分子变得越来越有创造力 我们注意到,联邦调查…...
ASP.NET Core认证原理和实现
ASP.NET Core认证原理和实现 AuthenticationHttpContextExtensions AuthenticationHttpContextExtensions 类是对 HttpContext 认证相关的扩展,它提供了如下扩展方法: public static class AuthenticationHttpContextExtensions {public static Task&l…...
基于OpenCV的图像颜色与形状识别的原理2
基于OpenCV的图像颜色与形状识别通常涉及以下几个步骤: 图像读取:使用OpenCV的cv2.imread()函数读取图像。预处理:可能包括图像的灰度转换、二值化、滤波等,以减少噪声和无关信息。颜色识别:颜色空间转换:…...
无法获取前置摄像头的预览图像?【Bug已解决-鸿蒙开发】
文章目录 项目场景:问题描述原因分析:解决方案:此Bug解决方案总结HarmonyOS和OpenHarmony区别和联系项目场景: 最近也是遇到了这个问题,看到网上也有人在询问这个问题,本文总结了自己和其他人的解决经验,解决了无法获取前置摄像头的预览图像的问题。 问题:前置摄像头…...
微信小程序的bindtap和catchtap的区别
一. 事件 1.事件是视图层到逻辑层的通讯方式。 2. 事件可以将用户的行为反馈到逻辑层进行处理。 3. 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。 二. 如何使用事件 1. 简单来说就是将事件绑定到组件上面,bi…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
