【GoF23种设计模式】02_单例模式(Singleton Pattern)

文章目录

  • 前言
  • 一、什么是单例模式?
  • 二、为什么要用单例模式?
  • 三、如何实现单例模式?
  • 总结


前言

提示:设计者模式有利于提高开发者的编程效率和代码质量:

GoF(Gang of Four,四人帮)设计模式由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者合著,介绍了23种经典的设计模式。
分为三大类:创建型模式、结构型模式和行为型模式。


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是单例模式?

单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供一个全局访问点来获取这个实例。这通常用于需要集中控制或管理资源的场景,例如数据库连接、线程池、配置文件读取等。

二、为什么要用单例模式?

使用单例模式的原因包括但不限于以下几点:

  • 资源控制:确保系统中某个资源仅有一个实例,避免资源浪费或冲突。
  • 全局访问:提供一个全局访问点,使得系统中的任何部分都可以方便地访问该实例。
  • 节省内存:因为只有一个实例存在,所以可以节省系统资源,特别是当对象占用大量内存时。
  • 状态共享:对于需要在多个地方共享状态的情况,单例模式可以确保状态的一致性。
  • 初始化成本高:如果对象的创建过程非常复杂或者耗时,那么使用单例模式可以在第一次使用时才进行创建,从而延迟初始化,提高性能。

三、如何实现单例模式?

单例模式的实现有多种方式,下面是一些常见的实现方法:

1、懒汉式(Lazy Initialization)
懒汉式是在第一次调用 getInstance 方法时才创建实例,这样可以实现延迟加载,节省资源。

public class Singleton {private static Singleton instance;private Singleton() {} // 私有构造函数防止外部实例化public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

优点:实现了真正的懒加载,即只有在真正需要的时候才会创建实例。

缺点:每次调用 getInstance 方法都需要进行同步,这可能会带来性能问题。

2、饿汉式(Eager Initialization)
饿汉式是在类加载时就创建实例,因此不需要同步,性能较好。

public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {} // 私有构造函数防止外部实例化public static Singleton getInstance() {return instance;}
}

优点:没有线程安全问题,也不需要同步,性能较高。

缺点:无论是否使用,都会创建实例,无法实现懒加载。

3、双重检查锁定(Double-Checked Locking)
双重检查锁定是一种优化过的懒汉式实现,减少了不必要的同步操作,提高了性能。

public class Singleton {private static volatile Singleton instance;private Singleton() {} // 私有构造函数防止外部实例化public static Singleton getInstance() {if (instance == null) { // 第一次检查synchronized (Singleton.class) {if (instance == null) { // 第二次检查instance = new Singleton();}}}return instance;}
}

优点:既实现了懒加载,又避免了每次调用 getInstance 时都进行同步,性能较高。

缺点:实现稍微复杂一些,而且需要理解Java内存模型和volatile关键字的作用。

4、静态内部类(Static Inner Class)
静态内部类是另一种实现懒加载的方式,利用了类加载机制确保线程安全。(常用)

public class Singleton {private Singleton() {} // 私有构造函数防止外部实例化private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}public static Singleton getInstance() {return SingletonHolder.INSTANCE;}
}

优点:线程安全,且实现了懒加载,性能良好,代码简洁。

缺点:与其它方式相比,可能不是最直观的理解方式。


总结

选择哪种实现方式取决于具体的应用场景和需求,后期会新增关于单例模式的具体应用场景。

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

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

相关文章

Node.js day-01

01.Node.js 讲解 什么是 Node.js,有什么用,为何能独立执行 JS 代码,演示安装和执行 JS 文件内代码 Node.js 是一个独立的 JavaScript 运行环境,能独立执行 JS 代码,因为这个特点,它可以用来编写服务器后端…

又要考试了

一、实现无名管道练习&#xff1a;父进程写入管道&#xff0c;子进程读取管道数据。 #include<myhead.h> int main(int argc, const char *argv[]) {int fd[2];char buff[1024]"王吕阳&#xff0c;崔庆权别卷了";char s[1024];if(pipe(fd)-1){perror("pi…

LoadBalancer负载均衡和Nginx负载均衡区别理解

LoadBalancer和Nginx都是用来做负载均衡用的&#xff0c;那二者有什么区别呢&#xff1f; Nginx服务器端的负载均衡&#xff1a; 所有请求都先发到nginx&#xff0c;然后再有nginx转发从而实现负载均衡。LoadBalancer是本地的负载均衡&#xff1a; 它是本地先在调用微服务接口…

Linux shell脚本练习(六)

清除系统默认文件缓存/tmp中超过30天未访问的文件 #!/bin/bash# 临时文件存放的目录 TEMP_DIR"/tmp" # 设置保留文件的天数 RETENTION_DAYS30# 判断临时目录是否存在 if [ ! -d "$TEMP_DIR" ]; thenecho "临时目录 $TEMP_DIR 不存在&#xff01;&quo…

【MQTT 编程】-API

文章目录 1 MQTTClient_message 结构体2 创建客户端对象3 连接服务端3 设置回调函数4 发布消息5 订阅主题和取消订阅主题5.1 订阅主题5.2 取消订阅 6 断开服务连接 1 MQTTClient_message 结构体 很重要的结构体&#xff0c;客户端应用程序发布消息和接收消息都是围绕这这个结构…

Technitium DNS Server的基本使用1(创建主区域,A记录,开启递归查询,递归到114.114.114.114)

Technitium DNS Server Technitium DNS Server搭建 搭建请看博主的上篇博客&#xff0c;内外网的方法都有 链接: 内网搭建Technitium DNS Server详细教程 登陆进去是以下界面 这个界面主要是监控&#xff0c;有访问的时候就会有波动 创建主区域&#xff0c;A记录 写上主区…

OpenAI 与 ChatGPT 的关系解析

OpenAI 与 ChatGPT 的关系解析 基本关系 OpenAI 是公司&#xff0c;ChatGPT 是产品 OpenAI 是一家人工智能研究公司ChatGPT 是 OpenAI 开发的一款 AI 聊天产品ChatGPT 使用的是 OpenAI 开发的 GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型 OpenAI 的…

Git简介和特点

目录 一、Git简介 二、Git特点 1.集中式和分布式 (1)集中式版本控制系统 (2)分布式版本控制系统 2.版本存储方式的差异 (1)直接记录快照&#xff0c;而非差异比较 3.近乎所有操作都是本地执行 一、Git简介 Git是目前世界上最先进的的分布式控制系统&#xff08;没有之一…

CSS学习记录15

CSS下拉菜单 使用CSS创建可悬停的下拉列表。 下拉式式菜单 .dropdown类使用position:relative,当我们希望将下拉内容放置在下拉按钮的正下方(使用position:absolute)时&#xff0c;需要使用该类。 .dropdown-content 类保存实际的下拉内容。默认情况下它是隐藏的&#xff0…

《国产单片机,soc的一些现实问题》

大概从口罩开始&#xff0c;芯片断供。在中低端市场&#xff0c;国外mcu&#xff0c;国外soc趁机抢占了大量市场份额。 但是因为大家都用国外了&#xff0c;价格优势依然不明显。 有一些没有核心技术的公司&#xff0c;或老板业务或采购出身&#xff0c;不懂技术。 在一堆芯片面…

AdminJS - 现代化的 Node.js 管理面板框架详解

AdminJS - 现代化的 Node.js 管理面板框架详解 什么是 AdminJS? AdminJS 是一个自动化的管理面板框架&#xff0c;专为 Node.js 应用程序设计。它可以让开发者快速构建功能强大的管理后台界面&#xff0c;而无需编写大量重复的代码。 主要特点 自动 CRUD 操作 自动生成增删…

RabbitMQ全局流量控制

RabbitMQ全局流量控制 流控机制流控是对什么进行控制&#xff1f;rabbitmq进程邮箱流控机制是什么&#xff1f; 流控原理流控原理流程 流控状态显示流控对象流控机制对象主要进程各进程状态情形分析 性能提升提升队列性能方式 当消息积压时&#xff0c;消息会进入到队列深处&am…

大数据平台

大数据行业应用持续升温&#xff0c;特别是企业级大数据市场正在进入快速发展时期。越来越多的企业期望实现数据孤岛的打通&#xff0c;整合海量的数据资源&#xff0c;挖掘并沉淀有价值的数据&#xff0c;进而驱动更智能的商业。随着公司数据爆发式增长&#xff0c;原有的数据…

鸿蒙生态的崛起:开发实践、认证路径与激励策略

目录 前言 鸿蒙生态能力和行业解决方案 1、鸿蒙创新能力 2、鸿蒙行业解决方案 中软鸿蒙生态业务布局 1、深度参与鸿蒙生态建设 2、提供一站式鸿蒙生态服务 &#xff08;1&#xff09;服务目录 &#xff08;2&#xff09;改造过程的关键点 &#xff08;3&#xff09;鸿…

Vue如何来处理动画

Vue 提供了多种方式来处理动画&#xff0c;使得创建动态用户界面变得简单而灵活。以下是几种关于 Vue 动画的技巧和最佳实践&#xff0c;帮助你更高效地在项目中实现动画效果&#xff1a; 1. 使用 <transition> 和 <transition-group> 组件 Vue 内置的 <trans…

指令遵循数据集IFEval介绍:中英双语

IFEval数据集介绍&#xff1a;评估大语言模型指令遵循能力 1. IFEval数据集提出的问题 随着大语言模型&#xff08;如GPT-4、PaLM 2等&#xff09;在自然语言任务中的广泛应用&#xff0c;模型的指令遵循能力&#xff08;Instruction Following&#xff09;成为一个重要评估指…

Rust中自定义Debug调试输出

在 Rust 中&#xff0c;通过为类型实现 fmt::Debug&#xff0c;可以自定义该类型的调试输出。fmt::Debug 是标准库中的一个格式化 trait&#xff0c;用于实现 {:?} 格式的打印。这个 trait 通常通过自动派生&#xff08;#[derive(Debug)]&#xff09;来实现&#xff0c;但你也…

【git使用】git patch操作的常用命令:patch -p1 < xxxx.patch

patch -p1 < xxxx.patch 是一个在 Unix/Linux 系统中常用的命令&#xff0c;其主要含义如下&#xff1a; 一、patch 命令 patch 是一个用于对文件进行补丁操作的工具。补丁文件&#xff08;通常是 .patch 文件&#xff09;包含了对原始文件的修改信息&#xff0c;这些修改可…

基于Qt的上位机通讯库

1.前言 做Qt上位机已经有两年的时间了&#xff0c;上位机主要是和下游器件打交道的&#xff0c;通过modbus、tcp、串口等协议来控制这些设备&#xff0c;通过一定的时序控制&#xff0c;完成所需要的工作流程。这其中最重要的就是通讯了&#xff0c;上位机开发过程中的相当一部…

《Kali Linux 软件源更换攻略:优化软件获取与系统更新》

KALI为什么要换源 速度提升 Kali Linux 默认的软件源服务器通常位于国外。在从这些国外源下载软件包、更新系统时&#xff0c;会受到网络带宽、网络延迟等因素的限制。例如&#xff0c;在中国&#xff0c;连接到国外服务器的网络速度可能较慢&#xff0c;尤其是在下载大型软件…