单例设计模式是什么?什么是 Singleton 单例设计模式?Python 单例(单件)设计模式示例代码

什么是 Singleton 单例设计模式?

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。

在这里插入图片描述

主要思想:

单例模式确保某个类只有一个实例,并提供了一个访问该实例的全局访问点。它常用于需要全局共享访问点的场景,例如日志记录器、数据库连接池、配置文件管理等。

主要角色:

  1. Singleton(单例类): 定义了一个静态方法来返回自身唯一的实例,并且该实例是静态成员变量。

在这里插入图片描述

工作流程:

  1. 将类的构造函数设为私有,以防止从外部直接实例化对象。
  2. 在类的内部创建一个静态私有成员变量来保存实例。
  3. 提供一个公共的静态方法来获取这个唯一的实例,如果实例不存在则创建,如果已存在则直接返回。

当使用单例模式时,有以下优点和缺点:

优点:

  1. 全局唯一实例: 单例模式确保一个类只有一个实例,提供了全局唯一的访问点,方便对实例的管理和控制。

  2. 节省系统资源: 由于单例模式只创建一个实例,可以节省系统资源和内存空间,特别是在频繁创建对象时有助于提高性能。

  3. 避免全局变量污染: 将状态保存在单例实例中可以避免全局变量的过度使用,减少了命名空间的污染。

  4. 提供了一个单一访问点: 可以通过单例对象来控制资源的访问和并发情况,使得资源的使用更加可控。

缺点:

  1. 全局状态: 单例模式引入全局状态,可能会增加系统的耦合度和复杂性,不利于单元测试和维护。

  2. 隐藏依赖关系: 单例模式隐藏了对象的创建方式和依赖关系,使得程序变得不透明,不利于追踪代码流程和理解程序逻辑。

  3. 滥用可能带来问题: 如果滥用单例模式,在某些情况下会导致性能问题、内存泄漏等,因此在使用时需要慎重考虑。

  4. 违反单一职责原则: 有时候单例类可能会承担过多的职责,违反了单一职责原则,导致类的职责不清晰。

  5. 线程安全问题: 在多线程环境下,单例模式需要考虑线程安全问题,可能需要额外的处理来保证线程安全性。

综上所述,单例模式在合适的情况下能提供全局唯一的访问点,节省资源和提高效率。但在不适合的场景下使用单例模式可能会引入一些问题,需要谨慎评估其利弊。


Python 实现单例设计模式示例代码(一):

class Singleton:_instance = Nonedef __new__(cls):if cls._instance is None:cls._instance = super().__new__(cls)return cls._instance# 使用示例
obj1 = Singleton()
obj2 = Singleton()print(obj1 is obj2)  # 输出:True,表明obj1和obj2是同一个实例

这个示例展示了一个简单的单例模式实现。在这个例子中,Singleton 类中的 _instance 变量用来存储实例,在创建实例时,先检查是否已经存在实例,如果不存在则创建,存在则直接返回已有的实例。

单例模式的实现方式还有多种变种,例如基于装饰器、基于元类等。在实际开发中,要根据具体情况选择最适合的实现方式。


Python 实现单例设计模式示例代码(二):

当需要管理全局状态或资源时,比如在一个游戏中管理玩家信息,可以使用单例模式来确保只有一个玩家管理器实例:

class PlayerManager:_instance = Nonedef __new__(cls):if cls._instance is None:cls._instance = super().__new__(cls)# 初始化玩家列表等资源cls._instance.players = []return cls._instancedef add_player(self, player_name):self.players.append(player_name)print(f"Added player: {player_name}")def remove_player(self, player_name):if player_name in self.players:self.players.remove(player_name)print(f"Removed player: {player_name}")else:print(f"Player {player_name} not found")def get_players(self):return self.players# 使用示例
player_manager1 = PlayerManager()
player_manager1.add_player("Alice")player_manager2 = PlayerManager()
player_manager2.add_player("Bob")print(player_manager1.get_players())  # 输出:['Alice', 'Bob']
print(player_manager1 is player_manager2)  # 输出:True

在这个示例中,PlayerManager 类用于管理玩家信息,它确保只有一个实例存在。无论创建多少次 PlayerManager 对象,都会得到同一个实例。这样,在不同的地方调用 PlayerManager 实例时,都能够操作同一份玩家列表信息。


使用单例设计模式时,需要注意哪些地方?

  1. 线程安全性: 如果应用涉及多线程,并且多个线程同时访问单例类,需要考虑线程安全问题。可以通过加锁或使用线程安全的方式来保证单例在多线程环境下的安全性。

  2. 延迟实例化: 如果实例化过程较为复杂,且不一定会用到单例,可以考虑延迟实例化,即在需要使用时再创建单例对象,以节省资源。

  3. 全局状态: 单例模式会引入全局状态,可能会增加系统的耦合性和复杂性。要谨慎考虑单例的使用场景,避免滥用。

  4. 测试难度: 单例模式可能会增加代码的测试难度,因为它引入了全局状态,可能需要额外的设置和清理来进行单元测试。

  5. 对外封装性: 为了保证单例的唯一性,通常需要将构造函数设为私有,这样外部无法直接创建对象,但也会限制了继承和扩展。

  6. 内存泄漏风险: 单例模式长期持有对象实例,如果没有及时释放资源,可能会导致内存泄漏问题,特别是在长时间运行的应用中。

  7. 多例模式误用: 有时候因为场景的误解,可能会误用单例模式,而需要多个实例。在这种情况下,应该避免使用单例模式,而是考虑其他模式或方式。

综上所述,虽然单例模式提供了一个方便的全局访问点,但在使用时需要权衡好利弊,避免滥用并考虑到单例可能引入的问题。


本文就到这里了,感谢您的阅读 。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇

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

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

相关文章

vatee万腾科技先锋之选:vatee创新力驱动着未来发展

在科技潮流的浩荡前行中,Vatee万腾崭新的科技先锋之选正以强大的创新力引领着未来的发展。Vatee万腾凭借其前瞻性的技术理念和卓越的创新实践,成为业界的引领者,为整个科技行业树立了标杆。 Vatee万腾不仅仅是一家科技公司,更是一…

React中StrictMode严格模式,导致开发环境,接口会请求两次或多次( useEffect 请求多次)

问题描述: 我在用 create-react-app时,开发环境,一进页面接口会请求两次或多次。 我在首页 useEffect里 请求一个接口,整个页面就在这里请求这一次接口。但 实际上请求了两次。我检查了代码,确定只调用了一次&#xf…

Go 异常处理流程

在 Go 语言中,panic、recover 和 defer 是用于处理异常情况的关键字。它们通常一起使用来实现对程序错误的处理和恢复。 1. defer 语句 defer 用于在函数返回之前执行一段代码。被 defer 修饰的语句或函数会在包含 defer 的函数执行完毕后执行。defer 常用于资源清…

基于SSM 离退休管理平台-计算机毕设 附源码 52629

ssm离退休管理平台 摘 要 随着社会的发展,社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景,运用软件工程原理和开发方法,它主要是采用SSM技术和mysql数据库来完成对系统的…

上海站活动回顾 | 聚焦私募视野,助力量化投研交易

11月16日下午,DolphinDB 携手华金证券,在上海成功举办了 D-Day 私募行业交流会,为大家带来了详实的私募行业场景解析、功能介绍、案例分享及现场演示。三十余位来自私募机构的核心策略研发、量化交易员、数据分析专家们齐聚现场,深…

Rust生态系统:探索常用的库和框架

大家好!我是lincyang。 今天我们来探索Rust的生态系统,特别是其中的一些常用库和框架。 Rust生态系统虽然相比于一些更成熟的语言还在成长阶段,但已经有很多强大的工具和库支持各种应用的开发。 常用的Rust库和框架 Serde:一个…

计算机网络之概述

一、概述 1.1因特网概述 定义 网络(Network)由若干结点(Node)和连接这些结点的链路(Link)组成。多个网络还可以通过路由器互连起来,这样就构成了一个覆盖范围更大的网络,即互联网(或互连网)因此,互联网是“网络的网络…

Nginx解决跨域问题的一些想法

参考博客https://blog.csdn.net/agonie201218/article/details/112562252,https://blog.csdn.net/Zisson_no_error/article/details/119357629。都是写得非常很好的文章 重中之重:一定要长眼睛,带脑子 通过跨域访问的报错,看清楚…

【开源】基于Vue.js的高校学院网站的设计和实现

项目编号: S 020 ,文末获取源码。 \color{red}{项目编号:S020,文末获取源码。} 项目编号:S020,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学院院系模块2.2 竞赛报名模块2.3 教…

软件工程--软件建模--结构化方法通俗语言总结(暴肝超详解)(包含数据流图、数据字典、ER图、结构化设计和优化......)

目录 结构化分析 数据流图DFD 定义数据字典 实体关系图(E-R图) 结构化设计 变换映射 事务映射 优化结构设计 实例分析 详细设计(过程设计) 结构化方法是一种系统化开发软件的方法,该方法基于模块化的思想&am…

nginx-编译安装-基础指令-信号

nginx 的编译与安装 nginx目录介绍 如果我们需要整合第三方模块,需要自己编译然此模块编译到nginx里面。apt和yum的安装只具有常用的基础功能。 下载nginx wget http://nginx.org/download/nginx-1.14.0.tar.gz/auto 目录 Changes 描述了一每个版本提供了那些特…

【JavaEE初阶】 JavaScript基础语法——贰

文章目录 🌲条件语句🚩if 语句🚩三元表达式🚩switch🚩循环语句🎈while 循环🎈continue🎈break🎈for 循环 🍀数组🚩创建数组🚩获取数组…

vue中使用echarts渐变柱状图 Cannot read properties of undefined (reading ‘graphic‘)解决方法

在使用渐变颜色时报错,Cannot read properties of undefined (reading ‘graphic’) echarts也下载了,引入了,就是报错,用不了new charts, 结果换了一个版本号就可以了,本来用的"echarts": "…

记录一次hiveserver2和namenode进程宕掉的排查

背景 最近发现集群主节点总有进程宕机,定位了大半天才找到原因,分享一下 排查过程 查询hiveserver2和namenode日志,都是正常的,突然日志就不记录了,直到我重启之后又恢复工作了。 排查各种日志都是正常的&#xff0…

Vue3 插槽 v-slot

插槽 视频链接:尚硅谷vue-插槽章节 不使用插槽的情况下 结果: 1 默认插槽 在子组件中只能有一个 结果: 2 具名插槽 #b是v-slot:b 的缩写 顾名思义就是指着名字去插入 结果: 3 作用域插槽 可以传递数据的插槽&#…

分享一些简单的英语问候语

昨天和一个朋友聊天,他问我最近有没有某个国家的客户?我说只有一两个,都已经好久没有联系了,上一次问候还是在九月份。他说从十月底开始就收到很多来自当地的询盘,你不妨问下客户最近是否有新的需求? 于是…

python 实现蚁群算法(simpy带绘图)

这里使用了蚁群算法求解了旅行商问题,同时结合了simpy来绘图 选择下一个食物的函数为: probability[i] pheromone[self.now][self.not_to_foods[i]] ** pheromone_w (1 / distance[self.now][self.not_to_foods[i]]) ** distance_w 该条路概率权重该点…

排序算法--插入排序

实现逻辑 ① 从第一个元素开始,该元素可以认为已经被排序 ② 取出下一个元素,在已经排序的元素序列中从后向前扫描 ③如果该元素(已排序)大于新元素,将该元素移到下一位置 ④ 重复步骤③,直到找到已排序的元…

【数据结构】树与二叉树(十八):树的存储结构——Father链接结构、儿子链表链接结构

文章目录 5.1 树的基本概念5.1.1 树的定义5.1.2 森林的定义5.1.3 树的术语 5.2 二叉树5.3 树5.3.1 树的存储结构1. 理论基础2. 典型实例 5.3.2 Father链接结构a. 定义树节点结构b. 创建新节点c. 主函数d. 代码整合 5.3.3 儿子链表链接结构a. 定义树节点结构b. 创建新节点c. 添加…

为什么录屏没声音?实用技巧大放送!

录屏已成为我们在数字时代记录和分享内容的重要方式之一。但有时,您可能会遇到录制视频却没有声音的问题。这个问题可能出现在不同的录屏软件中,导致许多人感到疑惑。在本文中,我们将探讨为什么录屏没声音,并提供两种解决方案&…