目录
一、单例模式的概述
二、单例模式的优缺点
三、在Python中,单例模式有以下几种实现方式
1.通过魔法方法__new__实现
2.通过模块的导入
3.通过装饰器实现
4.通过使用类实现
一、单例模式的概述
单例模式是一种常用的软件设计模式。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
注意:
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
从具体实现角度来说,就是以下三点:
- 1.单例模式的类只提供私有的构造函数,
- 2.类定义中含有一个该类的静态私有对象,
- 3.该类提供了一个静态的共有函数用于创建或获取它本身的静态私有对象。
二、单例模式的优缺点
优点:
(1) 由于单例模式在内存中只有一个实例,减少内存开支,特别是一个对象需要频繁地创建销毁时,而且创建或销毁时性能又无法优化,单例模式就非常明显了
(2) 由于单例模式只生成一个实例,所以,减少系统的性能开销,当一个对象产生需要比较多的资源时,如读取配置,产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。
(3) 单例模式可以避免对资源的多重占用,例如一个写文件操作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作
缺点:
(1) 单例模式没有抽象层,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。
(2) 单例类的职责过重,在一定程度上违背了“单一职责原则”。
(3) 滥用单例将带来一些负面问题,如:为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;
三、在Python中,单例模式有以下几种实现方式
1.通过魔法方法__new__实现
class Demo1(object):
def __new__(cls, *args, **kwargs):
# 判断单例是否存在:_instance属性中存储的就是单例
if not hasattr(cls,'_instance'):
# 如果单例不存在,初始化单例
cls._instance= super(类名,cls).__new__(cls,*args,**kwargs)
# 返回单例
return cls._instance
2.通过模块的导入
# cls_singleton.py
class Foo(object):
pass
instance = Foo()
#
import cls_singleton
obj1 = cls_singleton.instance
obj2 = cls_singleton.instance
# 原理:模块第二次导入从内存找的机制
3.通过装饰器实现
def singleton(cls):
# 创建一个字典用来保存类的实例对象
_instance = {}
def _singleton(*args, **kwargs):
# 先判断这个类有没有对象
if cls not in _instance:
_instance[cls] = cls(*args, **kwargs) # 创建一个对象,并保存到字典当中
# 将实例对象返回
return _instance[cls]
return _singleton
@singleton
class Demo3(object):
a = 1
def __init__(self, x=0):
= x
a1 = Demo3(1)
a2 = Demo3(2)
print(id(a1))
print(id(a2))
4.通过使用类实现
class Demo4(object):
# 静态变量
_instance = None
_flag = False
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
if not Demo3._flag:
Demo4._flag = True