设计模式Python版 单例模式

news/2025/1/30 1:57:11/

文章目录


前言

GOF设计模式分三大类:

  • 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。
  • 结构型模式:关注类和对象之间的组合,包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。
  • 行为型模式:关注对象之间的交互,包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。

一、单例模式

单例模式(Singleton Pattern)

  • 定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。

  • 解决问题:如何确保系统中一个类只能有一个实例?

  • 使用场景:

    • 当系统中需要一个类来控制资源的访问,确保资源不会因为多个实例的创建而产生冲突时。
    • 当整个系统的配置信息存放在一个对象中,并由一个实例来进行管理时。
    • 当需要限制一个类的实例只能有一个,比如数据库连接池、线程池、缓存等。
  • 优点:

    • 单例模式提供了对唯一实例的受控访问。也可以特定数量的实例。
    • 由于在系统内存中只存在一个对象,因此可以节约系统资源。
  • 缺点:

    • 单例类较难扩展,单例类的职责过重
    • 如果运行环境提供了自动垃圾回收技术,可能被回收销毁

在这里插入图片描述

二、单例模式实现方式

方式一:懒汉式,线程不安全

  • 使用类变量和类方法实现单例模式get_instance()类方法负责创建和返回类的唯一实例。
  • 在第一次调用get_instance()方法时实例化,在类加载时并不自行实例化,这种技术又称为延迟加载(Lazy Load)技术,即需要的时候再加载实例。
  • 在多线程环境下可能会有问题
python">class TaskManager:tm: "TaskManager" = Nonedef __init__(self):pass@classmethoddef get_instance(cls):if cls.tm is None:cls.tm = TaskManager() # 自行实例化return cls.tm# 使用单例
task_manager = TaskManager.get_instance()

方寸二:懒汉式,线程安全

  • 上述方式一可能会遇到线程安全问题。即如果有两个线程同时检查到 cls.tm 为 None 并尝试创建一个新的 TaskManager 实例,这就会导致创建了多个实例。
  • 还需要待进一步确认。因为在Python中,由于全局解释器锁Global Interpreter Lock,GIL的存在,即使是多线程程序,在任何给定时刻也只能有一个线程执行Python字节码。
  • 增加线程锁定保证线程安装,但会影响性能
python">import threadingclass TaskManager:tm: "TaskManager" = Nonelock = threading.Lock()def __init__(self):pass@classmethoddef get_instance(cls):with cls.lock:   # 进行线程锁定if cls.tm is None:cls.tm = TaskManager()return cls.tm# 使用单例
task_manager = TaskManager.get_instance()

方式三:Python模块级别的变量

  • 使用模块实现单例模式。Python的模块本身就是单例的,因为模块在第一次导入时会被加载并创建,之后的导入操作只是引用第一次创建的模块对象。
  • config是一个模块级别的变量,它在模块第一次被导入时创建,之后的导入操作都会使用这个已经创建的实例。
python"># 模块 my_config.py
class Config:def __init__(self):passconfig = Config()# 在其他文件中使用
from my_config import config

推荐:方式三 > 方式二 > 方式一

三、单例模式示例

使用模块实现单例模式

  • 将负载均衡器LoadBalancer设计为单例类,其中包含一个存储服务器信息的集合,每次随机选择一台服务器来响应客户端的请求
python"># 模块 balancer.py
import randomclass LoadBalancer:def __init__(self):self.server_list = []def add_server(self, server_name: str):self.server_list.append(server_name)def remove_server(self, server_name: str):if server_name in self.server_list:self.server_list.remove(server_name)def get_server(self):return random.choice(self.server_list)load_balancer = LoadBalancer()
  • 在其它文件中使用单例,客户端测试代码:
python">from balancer import load_balancerload_balancer.add_server("server 1")
load_balancer.add_server("server 2")
load_balancer.add_server("server 3")
load_balancer.add_server("server 4")for i in range(10):server = load_balancer.get_server()print(f"分发请求至服务器:{server}")### 输出结果
分发请求至服务器:server 4
分发请求至服务器:server 3
分发请求至服务器:server 2
分发请求至服务器:server 3
分发请求至服务器:server 1

四、单例模式在Django框架的应用

配置对象(Settings)

  • Django的配置对象是全局的,整个项目只有一个settings实例,这个实例包含了项目的所有配置信息。
  • Django启动时加载配置文件,并将其作为一个单例供整个系统使用。
python"># 模块 django/conf/__init__.py
...
settings = LazySettings()# 在其他文件中使用
from django.conf import settingsif settings.DEBUG:# Do something...

您正在阅读的是《设计模式Python版》专栏!关注不迷路~


http://www.ppmy.cn/news/1567770.html

相关文章

【山东乡镇界】面图层shp格式乡镇名称和编码wgs84坐标无偏移arcgis数据内容测评

标题中的“山东省乡镇界面图层shp格式乡镇名称和编码wgs84坐标无偏移arcgis数据”指的是一个地理信息系统(GIS)的数据集,专为山东省的乡镇区域设计。这个数据集包含了乡镇的边界信息,以Shapefile(shp)格式存…

【数据资产】数据资产管理概述

导读:数据资产管理在企业的数字化转型和业务发展中扮演着至关重要的角色。它直接关系到企业的决策效率、运营优化、业务创新以及风险防控等多个方面。数据资产作为企业的重要战略资源,能够为企业带来经济利益,其价值可能来自于数据本身的稀缺…

Unbutu虚拟机+eclipse+CDT编译调试环境搭建

问题1: 安装CDT,直接Help->eclipse Market space-> 搜cdt , install,等待重启即可. 问题2:C变量不识别vector ’could not be resolved 这是库的头文件没加好,右键Properties->C Build->Enviroment,增加…

前端性能优化指标 - DCL(触发时机、脚本对 DCL 的影响、CSS 对 DCL 的影响)

前端性能优化指标 DCL 1、概述 DCL(DOMContentLoaded)表示浏览器已经完全加载并解析了页面的初始 HTML 文档,同时完成了 DOM 树的构建,但需等待样式表、图片等外部资源的加载 2、触发时机 当 HTML 文档被完全加载和解析时触发 …

SQL进阶实战技巧:如何构建用户行为转移概率矩阵,深入洞察会话内活动流转?

目录 1 场景描述 1.1 用户行为转移概率矩阵概念 1.2 用户行为转移概率矩阵构建方法 (1) 数据收集 (2)定义状态 (3)数据预处理 (4)会话划分 (5)构建状态…

HarmonyOS简介:高效开发与测试

ArkTS语言 ArkTS是HarmonyOS优选的主力应用开发语言。 在TypeScript生态的基础上做了进一步拓展,保持了其基本风格,同时通过规范定义,强化开发期静态检查和分析,提升程序执行稳定性和性能。 如图所示代码示例 UI界面会显示一段…

利用ue5制作CG动画笔记

tips: 按住鼠标中键可以拖动枢轴点 在曲线编辑器中按住shift可以使曲线编辑保持在x轴 专业术语: CGI:计算机生成图象(computer-generated imagery)真实的不算,计算机生成的 Compositing:合…

代码随想录算法【Day34】

Day34 62.不同路径 思路 第一种&#xff1a;深搜 -> 超时 第二种&#xff1a;动态规划 第三种&#xff1a;数论 动态规划代码如下&#xff1a; class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n,…