Python设计模式-单例模式

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中,还存在着饱汉模式和饿汉模式:
饱汉模式:
在第一次被引用时,才将自己实例化。避免开始时占用系统资源,但是有多线程访问安全性问题。
饿汉模式:
在类被加载时就将自己实例化(静态初始化)。其优点是躲避了多线程访问的安全性问题,缺点是提前占用系统资源。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值