单例设计模式是什么?什么是 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.rhkb.cn/news/200751.html

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

相关文章

怎么做好品牌营销,小红书爆款笔记怎么做?

只要在小红书平台进行传播,能够尽可能多的创造爆款笔记,就是所有品牌方和达人的目标。今天来马文化传媒为大家分享下怎么做好品牌营销,小红书爆款笔记怎么做? 一、判断爆款笔记的三大指标 判断一篇笔记是否是爆款笔记,…

【攻防世界-misc】simple_transfer

1.下载并打开文件, 2.这个文件是一个pcap文件, 用wireshark打开,并按上图步骤操作, 会自动定位到有flag的这个信息行,这时需要右键追踪该信息的tcp流即可。 向下查找时,可以看到有一个pdf文件在这个里面&…

C++医学影像PACS系统源码,影像归档和通信系统全套源码

C医学影像PACS系统源码 PACS系统,意为影像归档和通信系统。它是应用在医院影像科室的系统,主要的任务就是把日常产生的各种医学影像(包括核磁,CT,超声,各种X光机,各种红外仪、显微仪等设备产生的…

许战海战略文库|三步成就技术品牌:奥迪如何打造Quattro技术品牌?

引言:在当前全球化和信息化快速发展的背景下,技术品牌的打造不仅是企业竞争力提升的重要途径,也是企业实现长远发展的基石。技术品牌的建设并非一蹴而就的过程,而是需要企业准确把握市场趋势发掘自身核心竞争力,并通过长期的积累和推广逐渐在市场中树立起良好的技术…

13.真刀实枪做项目---博客系统(页面设计)

文章目录 1.预期效果1.1博客列表页效果1.2博客详情页效果1.3博客登陆页效果1.4博客编辑页效果 2.实现博客列表页2.1实现导航栏2.2实现版心2.3实现个人信息2.4实现博客列表2.5博客列表页完整代码 3.实现博客正文页3.1引入导航栏3.2引入版心3.3引入个人信息3.4实现博客正文3.5博客…

uniapp和vue3+ts创建自定义下拉选择框组件

使用uniapp开发小程序的时候,使用了uview的ui组件,但是里面没有下拉选择组件,只有Picker 选择器,但是我们想要使用下拉选择的组件,所以需要自定义个一个下拉选择的自定义组件,我就只能自己动手创建这个自定…

【C++进阶之路】第四篇:set和map

文章目录 一、关联式容器健值对二、set & multiset三、map & multimap在这里插入图片描述 四、set和map底层原理 一、关联式容器健值对 关联式容器 & 键值对 二、set & multiset set & multiset 三、map & multimap map & multimap 四、set和…

Spring Framework IoC依赖注入-按Bean类型注入

Spring Framework 作为一个领先的企业级开发框架,以其强大的依赖注入(Dependency Injection,DI)机制而闻名。DI使得开发者可以更加灵活地管理对象之间的关系,而不必过多关注对象的创建和组装。在Spring Framework中&am…

将kali系统放在U盘中插入电脑直接进入kali系统

首先准备一个空白的 U 盘。 Kali Linux | Penetration Testing and Ethical Hacking Linux Distribution 在 Windows 上制作 Kali 可启动 USB 驱动器 Making a Kali Bootable USB Drive on Windows | Kali Linux Documentation 1. 首先下载 .iso 镜像 Index of /kali-images…

单链表OJ题--9.环形链表

9.环形链表 141. 环形链表 - 力扣(LeetCode) /* 解题思路: 定义快慢指针fast,slow, 如果链表确实有环,fast指针一定会在环内追上slow指针。 */typedef struct ListNode Node; bool hasCycle(struct ListNode *head) {Node* slow …

设计模式—结构型模式之享元模式

设计模式—结构型模式之享元模式 享元模式(Flyweight Pattern),运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。对象结构型。 在享元模式中可以共…

Arduino库之U8g2lib

某些图片、表格在手机竖屏状态下会显示不全,横屏显示即可。最好是用平板或电脑看。大部分内容摘自官网。 简介 U8g2 U8glib是用于单色显示屏的图形库,它可以用于51、Arduino、ARM控制显示屏,目前作者olikraus已经更新到version2了&#xff0…

瑞格心理咨询系统设置多个管理员的操作方法

使用瑞格心理咨询系统,需要设置多个admin权限的管理员账号来管理,咨询厂家答复只能有1个管理员,个人觉得不可能,于是开始折腾。 解决办法: 在没有数据字典的情况下, 通过遍历数据库,发现用户信…

16. @PostConstruct注解和开关原理(验证码开关、IP开关)

1►PostConstruct注解 PostConstruct是java自带的注解,会在java项目启动的时候先执行下面的方法 2►开关原理(验证码开关) 我们的项目具有验证码功能,旧版不支持关闭,新版已经支持关闭了。 我们打开页面“参数管…

使用 ClickHouse 做日志分析

原作:Monika Singh & Pradeep Chhetri 这是我们在 Monitorama 2022 上发表的演讲的改编稿。您可以在此处找到包含演讲者笔记的幻灯片和此处的视频。 当 Cloudflare 的请求抛出错误时,信息会记录在我们的 requests_error 管道中。错误日志用于帮助解…

Nginx - 本机读取服务器图像、视频

目录 一.引言 二.安装 Nginx 1.安装 By apt 2.安装 By 官网 三.配置 Nginx 1.Linux 机器配置 2.重启 Nginx 服务 3.本机查看机器文件 四.总结 一.引言 前面介绍了 GFP-GAN、PNG2GIF、GIF2PNG 等操作,我们生成的 video、gif、png 等形式的文件都存储在 lin…

【FPGA】Verilog:升降计数器 | 波纹计数器 | 约翰逊计数器 | 实现 4-bit 升降计数器的 UP/DOWN

目录 Ⅰ. 理论部分 0x00 升降计数器(UP DOWN Counter) 0x01 波纹计数器(Ripple Counter) 0x02 约翰逊计数器(Johnson Counter) Ⅱ. 实践部分 0x00 实现:升降计数器(4-bit&…

Unity - 实现模型动态伸长缩短,贴图不变形(材质球参数篇)

思路为修改模型材质球的Tiling参数&#xff0c;根据与自身localScale的值得到合适的比例&#xff0c;再修改Tiling值 var mat target.transform.GetComponent<Renderer>().material; var oriValue mat.mainTextureScale;//沿着Y轴伸缩 oriValue.y 1 * target.transfo…

使用DHorse发布SpringBoot项目到K8S

前言 在介绍DHorse的操作之前&#xff0c;先来介绍一下使用k8s发布应用的步骤&#xff0c;以SpringBoot应用为例进行说明。 1.首先从代码仓库下载代码&#xff0c;比如GitLab&#xff1b; 2.接着进行构建&#xff0c;比如使用Maven&#xff1b; 3.如果要使用k8s作为编排&am…

MySQL - 4种基本索引、聚簇索引和非聚索引、索引失效情况

目录 一、索引 1.1、简单介绍 1.2、索引的分类 1.2.1、主键索引 1.2.2、单值索引&#xff08;单列索引、普通索引&#xff09; 1.2.3、唯一索引 1.2.4、复合索引 1.2.5、复合索引经典问题 1.3、索引原理 1.3.1、主键自动排序 1.3.2、索引的底层原理 1.3.3、B 树和 B…