创建型模式之单例模式

举报
子都爱学习 发表于 2022/02/26 17:14:19 2022/02/26
【摘要】 单例模式保证一个类仅有一个实例,并且提供一个访问他的全局访问点。意图确保类有且只有一个对象被创建为对象提供一个访问点,以使程序可以全局访问对象控制共享资源的并行访问                            优点1、由于单例模式要求在全局内只有一个实例,因而可以节省比较多的内存空间; 2、全局只有一个接入点,可以更好地进行数据同步控制,避免多重占用; 3、单例可长驻内存,减少系统...

单例模式

保证一个类仅有一个实例,并且提供一个访问他的全局访问点。

意图

  • 确保类有且只有一个对象被创建
  • 为对象提供一个访问点,以使程序可以全局访问对象
  • 控制共享资源的并行访问

                           

优点

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


实现

1.模块级别的单例模式

其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

class Singleton(object):
    def foo(self):
        pass
singleton = Singleton()

这样我们一旦调用到上面第py文件就会产生一个singleton_by_module.pyc,以后我们每次调用都会直接引用这里面的代码。


2.函数级别的单例模式

装饰器里面的外层变量定义一个字典,里面存放这个类的实例.

def singleton(cls):
    # 单下划线的作用是这个变量只能在当前模块里访问,仅仅是一种提示作用
    # 创建一个字典用来保存类的实例对象
    _instance = {}

    def _singleton(*args, **kwargs):
        # 先判断这个类有没有对象
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)  # 创建一个对象,并保存到字典当中
        # 将实例对象返回
        return _instance[cls]

    return _singleton


@singleton
class A(object):
    a = 1

    def __init__(self, x=0):
        self.x = x

3.类级别的单例模式

饿汉式:

class Singleton(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(Singleton, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance

懒汉式:

class Singleton(object):
    """
    # 懒汉模式: 只有在使用时才创建单例对象,实例化时不创建
    """
    _instance = None

    def __init__(self):
        if not hasattr(Singleton, '_instance'):
            print("__init__ method called, but no instance created")
        else:
            print("instance already created:", self._instance)

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

4.Monostate单例模式

所有实例共享相同的状态

class Borg(object):
    _shared_state = {}
    def __new__(cls, *args, **kwargs):
        obj = super(Borg, cls).__new__(cls, *args, **kwargs)
        obj.__dict__ = cls._shared_state
        return obj

5.单例和元类

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

class Logger(metaclass=MetaSingleton):
    pass


缺点

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


应用

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

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。