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

设计模式——Singleton(单例)设计模式

摘要

本文介绍了单例设计模式的概念、实现和应用场景。单例模式确保某个类只有一个实例,节省资源并提供全局访问点。文章详细解释了单例模式的实现要素,包括私有构造方法、静态实例和公共静态方法,并探讨了其在数据库连接池、日志记录器和配置管理器等场景中的应用。

1. 单例设计模式是什么

1.1. 单例模式理解

单例设计模式(Singleton Pattern)是一种常见的创建型设计模式,旨在确保某个类在整个应用程序中只有一个实例,并提供一个全局访问点。这个模式的主要目的就是控制类的实例化过程,避免在程序运行期间多个实例的创建。它在需要全局唯一实例时非常有用,例如配置管理器、日志记录器等

1.2. 单例模式核心概念

单例模式的核心概念就是 唯一性 和 全局访问,通过私有化构造方法、提供全局访问点、延迟实例化、确保线程安全等手段来实现其目标。通过使用单例模式,可以有效地控制类的实例化和资源管理,避免冗余实例的创建。

单例设计模式的核心概念是确保某个类在整个应用程序中只有一个实例,并且提供一个全局访问点来访问该实例。其核心思想可以总结为以下几点:

  1. 唯一性:单例模式的主要目的是保证某个类只有一个实例。在程序的整个生命周期中,无论调用多少次获取实例的方法,都只能返回同一个实例。这避免了系统中多个相同对象的存在,确保了资源的统一管理和共享。
  2. 全局访问:单例模式提供一个全局访问点,使得该唯一实例可以在系统的任何地方被访问。通常这个访问点是通过一个静态方法实现的,外部通过该方法访问实例,而不需要直接创建实例。
  3. 延迟初始化:虽然单例模式保证了唯一性,但通常在实际使用时,实例的创建是延迟的(即懒加载)。实例只有在第一次被访问时才会被创建。这样可以避免在程序启动时就创建实例,节省资源,提升性能。
  4. 私有构造方法:为了确保类只能创建一个实例,单例模式通常会将构造方法设为私有的,阻止外部直接调用构造方法创建实例。这样,外部只能通过提供的静态方法来获取实例。
  5. 线程安全:在多线程环境下,需要保证实例的创建是线程安全的,防止多个线程同时创建多个实例。因此,单例模式在实现时需要考虑线程同步,以避免并发问题。
  6. 避免反射和序列化破坏单例:为了防止反射攻击或者序列化和反序列化破坏单例模式,一些实现方式(如枚举方式)能够防止通过反射创建新的实例。通过这种方式,确保了单例模式的安全性。

1.3. 单例设计模式作用

单例设计模式的作用可以总结为以下三点:

  1. 确保唯一性:单例模式保证某个类只有一个实例,避免了多个实例造成的资源浪费和管理混乱。例如,数据库连接池通常使用单例模式来确保在整个应用中只创建一个连接池实例,避免了多次创建和销毁连接池的开销。
  2. 提供全局访问点:单例模式通过静态方法提供一个全局访问点,使得系统的各个部分可以共享和访问该唯一实例。例如,日志记录器类通常使用单例模式,确保全局只有一个日志实例,且所有模块都通过该实例记录日志。
  3. 节省资源:单例模式通常采用懒加载(延迟实例化)策略,只有在第一次需要时才创建实例,从而节省系统资源。例如,配置管理器类可以使用单例模式来确保只加载一次配置文件,而不是每次读取时都创建新的实例。

2. 单例设计模式类实现

我们通过一个单例类 来确保该类只有一个实例,并且提供一个全局访问点来获取该实例。单例模式的实现通常需要包含以下几个核心要素:

  1. 私有构造方法:禁止外部通过构造方法直接创建实例。
  2. 静态实例:持有类的唯一实例。
  3. 公共静态方法:提供一个公共的访问点来获取唯一实例。

3. 单例模式使用场景

在实际工作中,单例模式有着广泛的应用,尤其是在需要确保全局唯一实例、共享资源或进行全局配置管理的场景。以下是几个常见的单例模式具体使用场景,并说明每个场景的作用:

3.1. 数据库连接池

场景:在开发大型系统时,数据库连接池通常会使用单例模式。一个数据库连接池是一个可以复用数据库连接的对象,在系统中通常只需要一个池来管理所有的数据库连接。通过单例模式,可以确保连接池在应用程序中只有一个实例,避免每次数据库操作都创建新的连接池实例,降低系统开销。

作用

  • 确保唯一性:通过单例模式,数据库连接池在整个应用中只有一个实例,避免了多次创建池的开销。
  • 资源共享:确保多个数据库操作共享同一个连接池实例,提高连接的复用率,节省系统资源。
  • 性能优化:通过连接池管理,可以减少数据库连接的创建和销毁的成本,提升系统的性能。

3.2. 日志记录器

场景:系统中的日志记录器通常使用单例模式来确保全局只有一个日志实例。日志系统需要将日志记录到文件或数据库等地方,如果每个模块都实例化一个新的日志对象,不仅浪费内存,还可能导致日志信息混乱。

作用

  • 确保唯一性:确保整个系统中只有一个日志记录器实例,避免了多个日志对象的创建。
  • 全局共享:所有模块通过该单一日志实例记录日志,确保日志格式和记录方式的一致性。
  • 降低内存消耗:避免了不必要的日志对象创建和销毁,提高了系统资源的利用率。

3.3. 配置管理器(RocketMQTemplate等类)

场景:配置文件(如数据库连接配置、系统参数等)在整个应用程序中可能被多个模块使用。配置管理器通常使用单例模式,确保所有模块都访问同一个配置实例,而不是每次都重新加载配置文件。

作用

  • 确保唯一性:只有一个配置管理器实例,避免了重复加载配置文件的资源浪费。
  • 全局访问:提供全局访问点,允许各个模块获取配置数据而无需重新读取文件或数据库。
  • 提高性能:减少重复读取配置文件的次数,提升系统性能。

3.4. 线程池管理(线程池创建)

场景:线程池用于管理线程的创建、销毁和复用,确保在多线程环境下能够合理使用系统资源。线程池通常实现为单例模式,以确保全局只有一个线程池实例来处理所有任务。

作用

  • 确保唯一性:整个系统共享同一个线程池实例,避免了多个线程池对象造成的资源浪费。
  • 线程管理:通过线程池集中管理线程,避免了每次任务执行时都创建新线程的开销。
  • 提升性能:通过复用线程,提高了任务执行效率,减少了频繁创建和销毁线程的成本。

3.5. 缓存管理(Redis配置类)

场景:在一些高性能的应用中,经常使用缓存来存储频繁访问的数据。缓存系统(例如 Redis 缓存管理器)通常会实现为单例模式,以确保整个应用中只有一个缓存实例,所有组件都能共享同一个缓存。

作用

  • 确保唯一性:通过单例模式,缓存系统只有一个实例,避免了多个实例占用多余的内存。
  • 全局共享:多个模块可以访问同一个缓存实例,提高缓存命中率,减少重复计算。
  • 性能优化:缓存数据减少了对数据库或其他资源的访问,提高了系统性能。

3.6. 事件分发系统

场景:在一些事件驱动的系统中,可能会有一个全局的事件分发系统,用来管理和分发各个组件之间的事件通知。此时,可以使用单例模式来确保事件分发系统在整个应用中只有一个实例。

作用

  • 确保唯一性:确保事件分发系统只会有一个实例,避免了事件处理混乱和资源浪费。
  • 全局访问:允许所有模块通过单一的事件分发器进行事件的发布和监听,确保事件流的一致性。
  • 高效管理:集中管理事件,提高了系统的可维护性和扩展性。

3.7. 应用程序状态管理

场景:在一些需要跟踪全局应用状态的系统中(例如,用户登录状态、权限管理等),可以使用单例模式来管理应用程序的全局状态。

作用

  • 确保唯一性:保证全局状态管理只有一个实例,避免多个状态实例导致的不一致性。
  • 简化管理:通过单一实例,简化应用状态的管理和共享,减少了不同模块之间的状态同步问题。
  • 提高一致性:通过集中管理应用状态,保证整个系统的状态一致性。

4. 单例设计模式的示例(Spring)

public class MyLogUtil {public static void debug(Logger logger, String message) {debug(logger, message, (Object[])null);}public static void debug(Logger logger, String message, Object... params) {if (logger != null && logger.isDebugEnabled()) {logger.debug(getLogString(message, params));}}public static void info(Logger logger, String message) {info(logger, message, (Object[])null);}
public abstract class CollectBaseHandler<T> implements CollectService<T>, InitializingBean {private static final Logger logger = LoggerFactory.getLogger(FeatureCollectBaseHandler.class);}
   public void dataSourceCollect(DecisionSessionContext sessionContext, FeatureContext featureContext) {try {LogUtil.info(logger, "”);} catch (HyxfException he){LogUtil.error(logger, "");}}

博文参考

《软件设计模式》

相关文章:

设计模式——Singleton(单例)设计模式

摘要 本文介绍了单例设计模式的概念、实现和应用场景。单例模式确保某个类只有一个实例&#xff0c;节省资源并提供全局访问点。文章详细解释了单例模式的实现要素&#xff0c;包括私有构造方法、静态实例和公共静态方法&#xff0c;并探讨了其在数据库连接池、日志记录器和配…...

深入理解 CSS 文本换行: overflow-wrap 和 word-break

前言 正常情况下&#xff0c;在固定宽度的盒子中的中文会自动换行。但是&#xff0c;当遇到非常长的英文单词或者很长的 URL 时&#xff0c;文本可能就不会自动换行&#xff0c;而会溢出所在容器。幸运的是&#xff0c;CSS 为我们提供了一些和文本换行相关的属性&#xff1b;今…...

Java-27 深入浅出 Spring - 实现简易Ioc-03 在上节的业务下手动实现IoC

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…...

kubernetes学习-使用metrics-server监控集群资源和查看日志

kubernetes学习-使用metrics-server监控集群资源和查看日志 一 、简介二、应用场景三、部署四、查看日志 一 、简介 Metrics Server 是一个用于 Kubernetes 集群的监控工具&#xff0c;它用于收集、存储和提供关于集群中各种资源的度量数据。Metrics Server 是 Kubernetes 中一…...

解决 Git Permission denied 问题

前言 push项目时出现gitgithub.com: Permission denied (publickey). fatal: Could not read from remote repository.Please make sure you have the correct access rights and the repository exists.出现这个问题表示你在尝试将本地代码推送到GitHub时&#xff0c;没有提供…...

CCNP_SEC_ASA 第三天作业

实验需求&#xff1a; ASA 使用列表放行 Outside 路由器到 DMZ 路由器的 WWW 流量并拒绝 Telnet 流量&#xff0c;当放行和拒绝流量匹配后产生日志通告。 提示&#xff1a;需要使能 ASA的日志功能和 DMZ路由器的 HTTP功能。 设备配置&#xff1a; ##此处展示各设备的配置&am…...

TypeError: Cannot read properties of null (reading ‘ce‘)

vue项目本地跑不起来&#xff0c;但是build之后能运行&#xff0c;本地报错 是因为你的vue版本不对&#xff0c;你的package可能是这样写的 这个表示你允许你的npm安装vue3的任意版本&#xff0c;但是build是按照这个版本来的&#xff0c;所以build之后能运行&#xff0c;本地运…...

AdminJS - 集成 MySQL 的现代化管理面板开发指南

AdminJS - 集成 MySQL 的现代化管理面板开发指南 MySQL 集成配置 首先需要安装必要的依赖&#xff1a; npm install adminjs adminjs/express express npm install adminjs/sequelize sequelize mysql2基础配置示例 const AdminJS require(adminjs) const AdminJSExpress …...

上传文件(vue3)

使用el-upload 先上传到文件服务器&#xff0c;生成url 然后点击确定按钮&#xff1a; 保存数据 <template><el-dialog top"48px" width"500" title"新增协议" :modelValue"visible" close"handleClose()">…...

【Win10 环境vscode配置boost】

文章目录 Boost exe版本windows环境安装vscode配置安装测试总结 Boost exe版本windows环境安装 这里不介绍boost源码安装&#xff0c;请自行网络搜索。本文要介绍的是window下单c文件&#xff08;cpp&#xff09;&#xff0c;调用boost库的执行配置。不涉及多文件。 安装文件下…...

中间件 redis安装

redis官网地址&#xff1a;Redis - The Real-time Data Platform 环境 CentOS Linux release 7.9.2009 (Core) java version "17.0.12" 2024-07-16 LTS 1、通过压缩包安装redis 1&#xff0c;远程下载redis压缩包&#xff0c;或去官网下载&#xff1a;Downloads …...

[java] 简单的熔断器scala语言案例

failureRateInterval时间内如果addEx(错误)达到 maxFailuresPerInterval 次数&#xff0c;则fused方法返回true,表示触发熔断&#xff0c;进入冷却期coolingInterval&#xff0c;冷却期内fused方法返回true&#xff0c;冷却期过后进入下一个错误统计周期。 scala语言完成 imp…...

【java】序列化的种类和使用场景

文章目录 序列化概述什么是序列化&#xff1f;序列化的作用 Java内置序列化java.io.Serializable接口使用ObjectOutputStream和ObjectInputStream优缺点分析 自定义序列化实现Externalizable接口自定义序列化方法适用场景 第三方序列化框架KryoProtobuf (Google Protocol Buffe…...

Qt5与Qt6中的高DPI缩放属性解析

在Qt5中&#xff0c;高DPI缩放默认是禁用的。为了启用它&#xff0c;开发者需要设置Qt::AA_EnableHighDpiScaling应用程序属性。然而&#xff0c;在Qt6中&#xff0c;高DPI缩放默认是启用的&#xff0c;并且不能被禁用。这种变化使得开发者在处理高分辨率屏幕时更加方便&#x…...

Mac使用总结

Mac 常用快捷键 复制&#xff1a;Cmdc粘贴&#xff1a;Cmdv只粘贴文档&#xff1a; ShiftCmdv行首&#xff1a; Cmd<行尾&#xff1a;Cmd>鼠标处选中到行首&#xff1a;ShiftCmd<鼠标处选中到行尾&#xff1a;ShiftCmd>选中整行&#xff1a;上面两个命令组合鼠标处…...

【日期规则】EXCEl 自定义日期匹配规则,学习基础知识,自由匹配场景

excel 新建规则工具路径&#xff1a;开始 - 条件格式 - 新建规则 B$1TODAY() 注意&#xff1a;新建规则后&#xff0c;要点击 条件格式 - 管理规则 - 应用于 要选择规则应用范围 使用场景&#xff1a; excel 做进度管理当中可以查看当天的情况&#xff1b;每周的学习规划 或…...

苹果电脑可以安装windows操作系统吗?Mac OS X/OS X/macOS傻傻分不清?macOS系统的Java支持?什么是macOS的五大API法王?

苹果电脑可以安装windows操作系统吗? 先抛开虚拟机安装&#xff0c;苹果电脑可以安装Windows操作系统。苹果公司提供了一个名为Boot Camp的软件&#xff0c;它允许用户在Mac电脑上安装Windows操作系统。通过Boot Camp&#xff0c;用户可以在启动电脑时选择是要进入macOS还是Wi…...

芋道SpringBoot配置Maven、创建SpringBoot项目、创建Web接口、读取配置信息

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列文章目录 第一章 芋…...

物理机内网穿透

前言&#xff1a; 本文主要讲述如何使用内网穿透以及其安全性。 将带领大家在公网上搭建几个常用靶场。 一&#xff0c;什么是内网穿透。 大多数情况下&#xff0c;我们的个人电脑都处于内网&#xff0c;即没有可公开访问的独立 IP 地址&#xff0c;因此其他内网用户找不到…...

Vue 3: 通过图片链接获取图片颜色,间接设置背景颜色

在现代Web开发中&#xff0c;动态获取和处理图像数据是一个常见的需求。例如&#xff0c;你可能希望自动提取一张图片的主色调&#xff0c;以便根据这些颜色进行UI主题调整或其他视觉效果的处理。本文将介绍如何在Vue 3项目中&#xff0c;通过一个图片链接获取图片的颜色信息。…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...