【23种常见程序设计模式及python实现】———— 单例模式

本文详细介绍了单例模式的定义、应用场景和Python中的多种实现方式,包括模块导入、魔法方法判断等,同时讨论了单例模式在并发场景下的问题及解决方案,探讨了其优缺点和实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系列文章目录

【23种常见程序设计模式及python实现】———— 概述



应用场景举例

现有一个数据库(用输出操作代替写入数据),程序的各个模块都可能要操作数据库(如:查询,保存, … )。

问题分析

  1. 我们可以创建一个类负责数据库操作
  2. 因为各个模块都可能要用到数据库操作,所以数据库对象的创建与销毁大概率是很频繁的,但是这两种操作都占有巨大的内存与耗时,如果多次操作肯定会降低程序效率。

单例模式的出场

如果我们把这个类比作 某种职业 ,那么每次创建我们就要招聘 一个员工
销毁就要裁剪掉一个员工,当然还要付给他们工钱 。这样耗时耗力,但是如果我们一心一意,从头到尾只招聘一个员工,那么我们就只需要付给这一个员工工钱,节约了不少成本,这就是单例

所以我们可以从头到尾只使用一个数据库类的实例化,这样就相当于只招聘了一个员工,实现了单例,节约了时间空间成本。

但是,我们从头到尾只是用一个变量,这也太不科学了,全部加 global 不好吧,所以接下来就要看到我们神奇的实现了

单例模式

定义

单例模式是指:保证一个类仅有一个实例,并提供一个访问它的全局访问点

实现(python)

这里有七种方法实现python中的单例模式,下面 一 一为大家介绍

其实,总的原则就是:保证一个类只要实例化一个对象,下一次再实例的时候就直接返回这个对象,不再做实例化的操作

第一类:模块导入的方式

第一类通过模块导入的方式,借用了模块导入时的底层原理实现。
当一个模块(py文件)被导入时,首先会执行这个模块的代码,然后将这个模块的名称空间加载到内存。
当这个模块第二次再被导入时,不会再执行该文件,而是直接在内存中找。
于是,如果第一次导入模块,执行文件源代码时实例化了一个类,那再次导入的时候,就不会再实例化。

这里只有一种方法:

singleton.py

class Demo(object):
  pass

instance = Demo()

test.py

import singleton

demo1 = singleton.instance
demo2 = singleton.instance
print(demo1 is demo2)

输出

True

第二类:通过魔法方法判断的方式

第二类主要是基于类和元类实现,在’对象’的魔法方法中判断是否已经实例化过一个对象
这类方式,根据实现的手法不同,又分为不同的方法,如:
通过类的绑定方法;
通过元类;
通过类下的__new__;
通过装饰器(函数装饰器,类装饰器)实现等。

通过类的绑定方法
class Student:
  _instance = None	# 记录实例化对象

  def __init__(self, name, age):
    self.name = name
    self.age = age

  @classmethod
  def get_singleton(cls, *args, **kwargs):
    if not cls._instance:
      cls._instance = cls(*args, **kwargs)
    return cls._instance

stu1 = Student.get_singleton('jack', 18)
stu2 = Student.get_singleton('jack', 18)
print(stu1 is stu2)
print(stu1.__dict__
### 使用Python实现设计模式 #### 单例模式 (Singleton Pattern) 单例模式确保某一个类只有一个实例存在,并提供全局访问点。下面展示了一个简单的单例模式实现方法: ```python class Singleton: __instance = None def __init__(self): if Singleton.__instance is not None: raise Exception("This class is a singleton!") else: Singleton.__instance = self @staticmethod def get_instance(): if Singleton.__instance is None: Singleton() return Singleton.__instance if __name__ == "__main__": s1 = Singleton.get_instance() s2 = Singleton.get_instance() print(s1 is s2) # True, 表明两个变量指向同一个对象[^3] ``` 此代码片段展示了如何创建一个仅能被实例化一次的对象,任何后续尝试都会抛出异常。 #### 模型—视图—控制器(MVC)模式 MVC是一种架构模式,用于分离应用程序的不同方面——数据模型、用户界面以及控制逻辑。这有助于减少业务逻辑与UI之间的紧密联系,从而提升程序的灵活性和可维护性[^2]。 虽然这里没有给出具体的Python代码例子来描述MVC的具体实施方式,但在实际操作中可以考虑使用Flask框架配合Jinja模板引擎作为视图(View),SQLAlchemy ORM库管理数据库中的Model部分,而Controller则由路由函数担当。 #### 命令模式(Command Pattern) 命令模式允许将请求封装成对象,从而使参数化后的不同请求排队或记录日志成为可能,还可以支持撤销功能。以下是命令模式的一个简单示例: ```python from abc import ABCMeta, abstractmethod class Command(metaclass=ABCMeta): @abstractmethod def execute(self): pass class LightOnCommand(Command): def __init__(self, light): self._light = light def execute(self): self._light.on() class SimpleRemoteControl: def set_command(self, command): self._slot = command def button_was_pressed(self): self._slot.execute() class Light: def on(self): print('Light is On') remote = SimpleRemoteControl() light = Light() command = LightOnCommand(light) remote.set_command(command) remote.button_was_pressed() # 输出 "Light is On" ``` 上述脚本定义了一种机制,使得调用方不必知道具体要执行的动作是什么,只需触发相应的命令即可完成特定的任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值