您的位置:首页 > 编程语言 > Python开发

Python设计模式-单例模式

2017-06-19 08:36 267 查看

Python设计模式-单例模式

基于Python3.5.2,代码如下

#coding:utf-8
import threading
import time

class Singleton(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls,'_instance'):
print("first")
orig = super(Singleton,cls)
cls._instance = orig.__new__(cls,*args,**kwargs)
return cls._instance
def __init__(self):
print("init")

class Bus(Singleton):
lock = threading.RLock()
def sendData(self,data):
self.lock.acquire()
time.sleep(3)
print("sending Signal Data ,",data)
self.lock.release()

class VisitEntity(threading.Thread):
my_bus = ""
name = ""
def getName(self):
return self.name
def setName(self,name):
self.name = name
def run(self):
self.my_bus = Bus()
self.my_bus.sendData(self.name)

if __name__ == "__main__":
for i in range(3):
print("Entity %d begin to run..."%i)
my_entity = VisitEntity()
my_entity.setName("Entity_"+str(i))
my_entity.start()


单例模式分析与解读

单例模式:

单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。


单例模式的应用场景:

1、生成全局惟一的序列号;
2、访问全局复用的惟一资源,如磁盘、总线等;
3、单个对象占用的资源过多,如数据库等;
4、系统全局统一管理,如Windows下的Task Manager;
5、网站计数器。
6、单个数据库连接对象。


解读:

在单例模式中,在类实现单例过程中,在多线程的情景下,有可能会创建多个实例,所以在单例的创建过程中,需要对生成单例的过程加锁,防止出现多次创建。
1、在Singleton类中,由于Python创建对象是通过__new__()方法创建,给Singleton添加_instance属性来保存创建的实例对象,在__new__()的过程中,如果有_instance则直接返回该实例对象,如果没有则先创建该实例对象然后在返回该对象。
2、在Bus类中,由于Bus继承自Singleton类,该Bus类可以继承Singleton的单例特性。在多线程模型中,Bus类中的sendData方法是需要依次发送消息,所以在sendData中加入线程锁,哪个线程先获得锁就先执行。
3、在VisitEntity类中,利用Python的多线程,进行并发执行。
程序运行结果如下:


Entity 0 begin to run...
first
Entity 1 begin to run...
init
init
Entity 2 begin to run...
init
sending Signal Data , Entity_0
sending Signal Data , Entity_1
sending Signal Data , Entity_2


Bus对象只生成了一次,当其他线程执行Bus()时,都只执行了__init__()方法,没有执行__new__()新建类的方法。


单例模式的优缺点:

优点:

1、由于单例模式要求在全局内只有一个实例,因而可以节省比较多的内存空间;
2、全局只有一个接入点,可以更好地进行数据同步控制,避免多重占用;
3、单例可长驻内存,减少系统开销。


缺点:

1、单例模式的扩展是比较困难的;
2、赋于了单例以太多的职责,某种程度上违反单一职责原则;
3、单例模式是并发协作软件模块中需要最先完成的,因而其不利于测试;
4、单例模式在某种情况下会导致“资源瓶颈”。


备注:

在java中,还存在着饱汉模式和饿汉模式:


饱汉模式:

在第一次被引用时,才将自己实例化。避免开始时占用系统资源,但是有多线程访问安全性问题。


饿汉模式:

在类被加载时就将自己实例化(静态初始化)。其优点是躲避了多线程访问的安全性问题,缺点是提前占用系统资源。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: