Python设计模式之单例模式
2018年12月13日 15:34

单例模式

单例模式(Singleton Pattern)是最常用的一种设计模式,是一种非常常用的创建型设计模式。什么场景会用到单例模式呢?就是在系统工程中只想创建单个实例对象,比如数据库连接池,Redis连接池,服务监控中心等。这个场景下,如果存在多个实例对象,那么会有无法预测的异常。同时,在设计单例模式时,需要考虑的很重要的因素就是并发性,即多线程调用时是否会存在多个线程。那么,如何设计使用单例模式呢?

经典单例模式

最经典的单例模式实现非常简单,主要是:先判断类是否有这个实例,如果没有该实例,则生成一个实例;如果已经存在了一个实例,那么提供这个实例。算法代码如下:

76.png

运行如下代码,得到如下结果:

77.png

由此可见,s和t为同一个实例,即Singleton类实现了单例模式。

多线程单例模式

上述代码实现了单例模式,但是是否支持多线程呢?我们可以做个测试:

78.png

运行结果如下:

79.png

似乎是没有问题的。实际呢?这是因为初始化生成对象的时间比较短,如果生成对象的时间比较长呢?我们应用sleep函数来模拟这种场景。代码如下:

80.png

运行后的结果呢?我们可以看到产生了不同的对象:

81.png

也就是说,这种单例模式在多线程下是失效的,我们需要改进实现方式。那么,在多线程下如何实现单例模式呢?最经典的方式,就是加锁。多线程下单例模式的实现如下:

82.png

我们可以再次测试一下,如果初始化实例时间比较长的情况下,是否会产生多个实例。测试代码如下:

83.png

运行结果如下:

84.png

由此可以看出,确实只生成了单个实例,well done。

运用元类实现单例模式

元类,是一个类的类,所以,该类是元类的实例。在Python中,一切都为对象,那么,对象都会有类型。看一下如下代码:

85.png

运行结果如下:

86.png

那么,这表明,str类型的元类是type,即str是type类型的一个类。

元类可以控制类创建和对象的实例化,所以可以用于创建单例。Python代码实现如下(已经加入了锁来实现多线程):

87.png

运用模块实现单例模式

默认情况下,Python中所有的模块都是单例模式,这是由于Python中的导入行为所决定的。Python中运用模块导入主要做了以下工作:

1、判断该模块是否导入;

2、如果模块已经导入,则返回模块的对象;否则,如果没有导入,则导入并实例化。

Python实现如下:

88.png

在使用时,可以按照如下方式使用:

89.png

小结

本文介绍了三种单例模式的实现方式,其中Python中的模块都是单例,这也是实现单例模式最简单的方式,另外,本文介绍了通过__new__以及元类实现单例模式的方法,在实现的过程中,考虑了多线程。

774 213

上一篇:设计模式之抽象工厂模式

下一篇:蚂蚁爬杆问题

相关文章

旗下产品

软件IP代理 企业HTTP代理 开放HTTP代理 高速硬件IP代理
@ 2016 - 2024.猎鹰网安IP代理, All rights reserved. 鄂ICP备18017015号-4
禁止利用本站资源从事任何违反本国(地区)法律法规的活动
新闻中心 | 其他新闻 | 帮助文档