python设计模式之单例设计模式


一、理解单例设计模式

        单例模式提供的机制:确保类有且只有一个特定类型的对象,并提供全局访问点。

        特性:

           1.确保类有且只有一个对象被创建

           2.为对象提供一个访问点,以使程序可以全局访问该对象

           3.控制共享资源的并行访问。

         解决了什么问题:避免了同一资源产生相互冲突的请求。(用于日志记录,数据库操作,打印机后台处理程序)

示例:


# encoding: utf-8

# 使用单例模式创建类
class Singleton(object):
    # 创建新类前,先调用__new__
    def __new__(cls):
        # hasattr :判断是否有instance属性,
        # if 没有就创建,if 有就直接返回
        if not hasattr(cls,"instance"):
            cls.instance = super(Singleton,cls).__new__(cls)
            # print(cls.instance)
        return cls.instance

# 未使用单例模式创建类
class Singleton2(object):
    pass

# 用单例模式创建两个类
s0 = Singleton()
print ("Object created", s0)
s1 = Singleton()
print ("Object created", s1)

# 用非单例模式创建两个类
s2 = Singleton2()
print ("Object created", s2)
s3 = Singleton2()
print ("Object created", s3)


     输出:

('Object created', <__main__.Singleton object at 0x02598250>)
('Object created', <__main__.Singleton object at 0x02598250>)
('Object created', <__main__.Singleton2 object at 0x02598270>)
('Object created', <__main__.Singleton2 object at 0x02598290>)

二、单例设计模式中的懒汉式实例化

      特性:保证了需要使用的时候才创建对象。(防止导入模块,但没有使用,造成的浪费)

      示例:

# encoding: utf-8

class Singleton:
    __instance = None
    def __init__(self):
        if not Singleton.__instance:
            print ("__init__ method called..")
        else:
            print ("Instance already created:",self.getInstance())

    @classmethod
    def getInstance(cls):
        if not cls.__instance:
            cls.__instance = Singleton()
        return cls.__instance
s = Singleton() # 初始化,但不创建
print("Object created", Singleton.getInstance())# 使用的时候创建
s1 = Singleton() 




三、模块级别的单例模式

        默认情况python所有的模块都是单例,python模块的工作方式:

     1.检查一个模块是否已经导入

     2.如果导入,返回该模块对象。如果没导入,导入模块,并实例化。


四、Monostate单例模式

       单态单例模式:所有对象共享相同状态。(关心的是状态和行为,而不是同一性)


       示例:

# encoding: utf-8

class Borg:
    __shared_state = {"1":"2"}
    def __init__(self):
        self.x = 1
        self.__dict__ = self.__shared_state
        pass

b = Borg()
b1 = Borg()
b.x = 4

print ("Borg Object 'b': ",b) # b和b1不是同一个对象
print ("Borg Object 'b1': ",b1)
print ("Borg State 'b': ",b.__dict__) # b和b1共享状态
print ("Borg State 'b1': ",b1.__dict__)



五、单例和元类

        元类概念:元类是类的类。(a = 5 ,type(a)  为 int ,type(int) 为 type)

        元类示例:

# encoding: utf-8

class MyInt(type):
    def __call__(cls, *args, **kwds):
        print ("**** Here is My int ****",args)
        print ("Now do whatever you want with these objecys...")
        return type.__call__(cls, *args, **kwds)

class int(metaclass = MyInt):
    def __init__(self, x, y):
        self.x = x
        self.y = y

i = int(4,5)


        元类的单例实现:

# encoding: utf-8

class MetaSingleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(MetaSingleton,cls).__call__(*args,**kwargs)
        return cls._instances[cls]

class Logger(metaclass = MetaSingleton):
    pass

logger1 = Logger()
logger2 = Logger()
print (logger1,logger2)



        输出:

<__main__.Logger object at 0x005AB070> <__main__.Logger object at 0x005AB070>


六、单例模式I

        场景:多个web应用共享一个数据库,为了避免数据库操作冲突,采用单例模式

# encoding: utf-8
import sqlite3

class MetaSingleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls.instances:
            cls._instances[cls] = super(MetaSingleton,cls).__call__(*args,**kwargs)
        return cls._instances[cls]

class Database(metaclass = MetaSingleton):
    connection = None
    def connect(self):
        if self.connection is None:
            self.connection = sqlite3.connect("db.sqlite3")
            self.cursorobj = self.connection.cursor()
        return self.cursorobj

db1 = Database.connect()
db2 = Database.connect()

print ("Datebase Objects DB1", db1)
print ("Datebase Objects DB2", db2)


七、单例模式II

        场景:运行状况监控服务。我们对监控对象的操作肯定是同一个,所以用单例模式实现。

# encoding: utf-8
class HealthCheck:
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not HealthCheck._instance:
            HealthCheck._instance = super(HealthCheck,cls).__new__(cls,*args,**kwargs)
        return HealthCheck._instance

    def __init__(self):
        self._servers = []

    def addServer(self):
        self._servers.append("Server 1")
        self._servers.append("Server 2")
        self._servers.append("Server 3")
        self._servers.append("Server 4")
    def changeServer(self):
        self._servers.pop()
        self._servers.append("Server 5")

hc1 = HealthCheck()
hc2 = HealthCheck()

hc1.addServer()
print ("Schedule health check for server (1)..")
for i in range(4):
    print ("Checking ",hc1._servers[i])

hc2.changeServer()
print ("Schedule health check for server (2)..")
for i in range(4):
    print ("Checking ",hc2._servers[i])




八、单例模式的优缺点

    1.优点:

              1.1 减少资源的过度使用如在:线程池、缓存、对话框、注册表等

    2.缺点:

              2.1全局变量可能在某处已经被误改。

              2.2同一个对象可能创建多个引用。

              2.3依赖于全局变量的类都会耦合成全局数据,耦合度增加。



注:例子在python3中运行

本系列项目代码地址:Python-design-pattern


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若云流风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值