您当前的位置: 首页 >  彭世瑜 Python

Python:设计模式之单例模式

彭世瑜 发布时间:2019-06-12 12:00:40 ,浏览量:1

单例模式: 1、确保类有且只有一个对象被创建 2、为对象提供一个全局访问点 3、控制共享资源的并行访问

实现单例最简单的方式: 使构造函数私有化,并创建一个静态方法来完成对象初始化

使用场景: 一个类要求只有一个实例对象

单例模式的缺点 1、全局变量可能被误修改 2、对同一个对象创建多个引用 3、所有依赖于全局变量的类都会由于一个类的改变而紧密耦合为全局数据,从而可能在无意中影响另一个类

一、经典的单例模式

只允许Singleton类生成一个实例

# -*- coding: utf-8 -*-


class Singleton(object):
    def __new__(cls):
        if not hasattr(cls, "_instance"):
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance


if __name__ == '__main__':
    s1 = Singleton()
    s2 = Singleton()

    print(s1)
    print(s2)
    print(s1 == s2)
    print(s1 is s2)
"""


True
True
"""

二、懒汉式实例化

实际对象创建发生在 get_instance()

# -*- coding: utf-8 -*-


class Singleton(object):
    __instance = None

    def __init__(self):
        if not Singleton.__instance:
            print("create...")
        else:
            print("already exist...")

    @classmethod
    def get_instance(cls):
        if not cls.__instance:
            cls.__instance = Singleton()
        return cls.__instance


if __name__ == '__main__':
    s1 = Singleton.get_instance()  # 实例化

    s2 = Singleton.get_instance()  # 已存在,不会实例化

    print(s1)
    print(s2)
    print(s1 == s2)
    print(s1 is s2)
"""
create...


True
True
"""

三、单态模式 Monostate

所有对象共享相同的状态

# -*- coding: utf-8 -*-


class Borg(object):
    __data = {"age": 23}

    def __init__(self):
        self.__dict__ = self.__data


if __name__ == '__main__':
    b1 = Borg()
    b2 = Borg()

    # b1 和 b2是不同的对象,共享了相同的属性
    print(b1)
    print(b2)

    # 修改b1对象, b2对象的属性也变化了
    b1.name = "Tom"

    print(b1.__dict__)
    print(b2.__dict__)

"""


{'age': 23, 'name': 'Tom'}
{'age': 23, 'name': 'Tom'}
"""
四、基于元类的单例

元类控制类的实例化

# -*- coding: 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


if __name__ == '__main__':
    logger1 = Logger()
    logger2 = Logger()

    print(logger1)
    print(logger2)

"""


"""
五、单例模式应用一

对数据库进行同步操作

# -*- coding: 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]


import sqlite3


class Database(metaclass=MetaSingleton):
    connection = None

    def __init__(self, db_url):
        self.db_url = db_url

    def get_cursor(self):
        if self.connection is None:
            self.connection = sqlite3.connect(self.db_url)
            self.cursor = self.connection.cursor()

        return self.cursor


if __name__ == '__main__':
    db_url = "db.sqlite3"
    cursor1 = Database(db_url).get_cursor()
    cursor2 = Database(db_url).get_cursor()

    print(cursor1)
    print(cursor2)
"""


"""

六、单例模式应用二

监控服务器,共享服务器数据

# -*- coding: utf-8 -*-


class HealthCheck(object):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(HealthCheck, cls).__new__(cls, *args, **kwargs)
        return cls._instance

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

    def add_server(self, server):
        self.servers.append(server)

    def pop_server(self):
        return self.servers.pop()

    def show_server(self):
        print("*" * 10)
        for server in self.servers:
            print(server)
        print("*" * 10)


if __name__ == '__main__':
    h1 = HealthCheck()

    h2 = HealthCheck()

    h1.add_server("server1")
    h1.add_server("server2")
    h1.add_server("server3")

    h2.pop_server()

    h2.show_server()
    """
    **********
    server1
    server2
    **********
    """
总结

1、当要求一个类只有一个对象时,就可以使用单例模式 2、经典单例模式,允许多次实例化,但返回同一个对象 3、Borg或Monostate单态模式允许创建共享相同状态的多个对象 4、单例模式可应用于多个服务间,实现一致的数据库操作

参考: 《python设计模式第2版》第二章 单例设计模式

关注
打赏
1688896170
查看更多评论

彭世瑜

暂无认证

  • 1浏览

    0关注

    2727博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0553s