引言¶
在面向对象的世界里,对象是对客观事物的抽象,类是对对象的抽象。它们之间的关系是,对象是类的实例,类是对象的模板。
这段文字表述起来费劲,理解起来也费劲,还是讲生活中的例子吧。比如说“大河”,一联想到这个词,不同的人脑海中的印象是不一样的,有的是“大漠孤烟直,长河落日圆”,有的是“春江潮水连海平,海上明月共潮生”,有的是“星垂平野阔,月涌大江流”。在这个例子中,大河可以认为是一个类,大河具有所有河流的共性特征,如有河堤,有长度,会流向大海等特性,而几句诗中的“石羊河”、“浏阳河”、“长江”等分别是大河的一个实例化对象。
在大河的例子中,一个大河类可以有多个不同的实例。可是,我们今天的主角-单例模式,应用单例模式的类却只能有一个实例。
比如我们常见的操作系统的任务管理器,它就是一个单例模式的实现。
定义¶
单例模式(singleton pattern):确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。 这个定义有三个要点
- 某个类只能有一个实例
- 类应当自行创建这个实例
- 它必须向整个系统提供这个实例
UML结构¶
角色:单例本身
优缺点¶
优点¶
- 应用单例模式实例化类在应用程序域中只存在一个对象,满足业务需要的同时,无疑也能降低内存消耗,提高计算机性能。
- 由于实例化的过程由类本身完成,可方便地选择实例时机。
缺点¶
- 由于单例模式通常为单一类且不允许继承,所以它的扩展能力受限。
- 由于上一点的原因,单例类通常承载了过多的职能,违反了单一职责原则。
实例¶
Lilei和Hanmeimei经过多年的爱情长跑,终于迈入婚姻的殿堂。婚后不久,就有了爱情的结晶,小朋友名叫LittleMango。
In [6]:
class SingletonBase(type):
def __init__(self,*args,**kwargs):
self._instance=None
super().__init__(*args,**kwargs)
def __call__(self,*args,**kwargs):
if self._instance is None:
self._instance=super(SingletonBase,self).__call__(*args,**kwargs)
return self._instance
class LittleMango(metaclass=SingletonBase):
def show_my_age(self):
print('I\'m 5 years old')
if __name__ == "__main__":
s1=LittleMango()
s2=LittleMango()
print('s1:',id(s1))
print('s2:',id(s2))
通过上面的实例,我们看见s1和s2引用了同一个内存地址,这样,我们就实现了单例模式。在项目应用中,如果把SingletonBase封装起来,需要实现单例模式的地方继承此类即可。