3分钟学会设计模式 -- 单例模式

►单例模式

►使用场景

在编写软件时,对于某些类来说,只有一个实例很重要。例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统中可以多次查询数据库,但是只需要一个连接,而不是每次查询都重新创建一个连接,因为重复创建数据库连接会浪费内存资源。因此这种情况下确保系统中某个对象的唯一性即一个类只能有一个实例非常重要。

如何保证一个类只有一个实例并方便访问呢?定义一个全局变量可以确保对象随时可以访问,但不能防止实例化多个对象。一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的使用场景。

►python实现

python中实现单例模式的方法很多,常用方法如下:

重写__new__

类实例化时是调用__new__方法创建对象的,所以只要控制__new__方法创建对象是只生成一个实例即可。

python 复制代码
class DB:
    instance = None
 
 
    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super().__new__(cls, *args, **kwargs)
        return cls.instance
db1 = DB()
db2 = DB()
print(db1)
print(db2)

运行代码结果如下:

python 复制代码
<__main__.DB object at 0x000001BD06E55F70>
<__main__.DB object at 0x000001BD06E55F70>

►装饰器

将类的唯一实例保存在类属性上,然后通过类装饰器,在实例化时检查这个属性来控制只生成一个实例。

python 复制代码
def single_obj(cls):
    def wrapper(*args, **kwargs):
        if cls.instance is None:
            cls.instance = cls(*args, **kwargs)
        return cls.instance
    return wrapper
 
@single_obj
class DB:
    instance = None
 
db1 = DB()
db2 = DB()
print(db1)
print(db2)

运行代码结果如下:

python 复制代码
<__main__.DB object at 0x000001E485395970>
<__main__.DB object at 0x000001E485395970>

►元类

python中元类是用于创建类对象的类,类对象创建实例对象时一定会调用__call__方法,因此重写元类的__call__方法,保证在调用__call__时只创建一个实例即可。

python 复制代码
class SingleObj(type):
    def __call__(cls, *args, **kwargs):
        if getattr(cls, 'instance', None) is None:
            cls.instance = super().__call__(*args, **kwargs)
        return cls.instance
 
class DB(metaclass=SingleObj):
    pass
 
db1 = DB()
db2 = DB()
 
print(db1)
print(db2)

代码运行结果如下:

python 复制代码
<__main__.DB object at 0x00000252D5AE4F70>
<__main__.DB object at 0x00000252D5AE4F70>

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

相关推荐
野犬寒鸦15 分钟前
力扣hot100:相交链表与反转链表详细思路讲解(160,206)
java·数据结构·后端·算法·leetcode
ytadpole1 小时前
揭秘设计模式:工厂模式的五级进化之路
java·设计模式
计算机毕业设计木哥1 小时前
计算机毕设选题:基于Python+Django的B站数据分析系统的设计与实现【源码+文档+调试】
java·开发语言·后端·python·spark·django·课程设计
失散131 小时前
分布式专题——1.2 Redis7核心数据结构
java·数据结构·redis·分布式·架构
用户3721574261351 小时前
Python 实现 HTML 转 Word 和 PDF
java
a587691 小时前
Java核心概念精讲:TCP与UDP的区别、Java NIO的几个核心组件与HTTP和HTTPS的区别等(46-50)
java·面试·nio
烛阴2 小时前
【TS 设计模式完全指南】用工厂方法模式打造你的“对象生产线”
javascript·设计模式·typescript
JosieBook2 小时前
【程序人生】有梦想就能了不起,就怕你没梦想
程序人生·职场和发展
渣哥2 小时前
ConcurrentHashMap 的 get 要不要加锁?一次“多此一举”的心路历程
java
愿你天黑有灯下雨有伞2 小时前
一种基于注解与AOP的Spring Boot接口限流防刷方案
java·spring boot·后端