Python 设计模式:单例模式

简介: 单例模式可能是最简单的设计模式,单例是非常通用的对象。让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。

前言


单例模式可能是最简单的设计模式,单例是非常通用的对象。让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。


我们可以将船的船长视为单例模式的现实生活中的例子。在船上,他是负责人。他负责重要的决定,由于这一责任,他收到了一些请求。


网络异常,图片无法展示
|


如前所述,单例模式的一个用例是创建一个维护程序全局状态的单个对象。其他可能的用例如下:

  • 控制对共享资源的并发访问;例如,管理与数据库的连接的对象类
  • 横向的服务或资源,因为它可以从应用程序的不同部分或由不同的用户访问并完成其工作;例如,日志记录系统或实用程序核心的类
class Singleton:
    """Definition of a Singleton object."""
    singleton_instance = None
    def __init__(self):
        """
        Override the initialization 
        mechanism, returning only the single instance.
        """
        ...
    @staticmethod
    def get_singleton():
        """
        Method for fetching the Singleton instance.
        Is static so that it can be accessed everywhere.
        """
        ...
    @staticmethod
    def update_singleton(val):
        """
        Method for setting value of Singleton instance.
        Is static so that it can be accessed everywhere.
        """
        ...

存储在 Singleton 实例中的数据是任意的。重要的是,无论数据,呼叫者和范围如何,Singleton 对象都会返回同一实例。这使得单元在实现诸如全局设置或运行配置之类的内容时有用。


单例例子


使用下面的代码片段来播放 Active Singleton 实现。尝试用数据结构(例如字典)替换可变 Singleton_instance,并查看 Getter 和 Setter 的实现如何更改。尝试编写一些共享 Singleton 实例的功能。

class Singleton:
  """Definition of a Singleton object."""
  # Maintain state of Singleton
  singleton_instance = None
  def __init__(self):
    """Override the initialization mechanism."""
    if Singleton.singleton_instance is None:
      Singleton.singleton_instance = self
  @staticmethod
  def get_singleton():
    """
    Method for fetching the Singleton instance.
    Is static so that it can be accessed everywhere.
    """
    if Singleton.singleton_instance is None:
      Singleton()  # Call __init__ to initialize instance
    return Singleton.singleton_instance
  @staticmethod
  def update_singleton(val):
    """
    Method for setting value of Singleton instance.
    Is static so that it can be accessed everywhere.
    """
    if Singleton.singleton_instance is None:
      Singleton()  # Call __init__ to initialize instance
    Singleton.singleton_instance = val
Singleton.update_singleton("Michael")
print("Value in Singleton instance is: " + Singleton.get_singleton())
Singleton()  # Try to create a new Singleton instance
print("Value in Singleton instance is STILL: " + Singleton.get_singleton())


单例模式也可以通过使单例类使用元类(其类型,具有先前定义的元类)来实现。根据需要,元类的 __call__() 方法保存的代码可确保只能创建类的一个实例:

class SingletonMeta(type):
    """
    The Singleton class can be implemented in different ways in Python. Some
    possible methods include: base class, decorator, metaclass. We will use the
    metaclass because it is best suited for this purpose.
    """
    _instances = {}
    def __call__(cls, *args, **kwargs):
        """
        Possible changes to the value of the `__init__` argument do not affect
        the returned instance.
        """
        if cls not in cls._instances:
            instance = super().__call__(*args, **kwargs)
            cls._instances[cls] = instance
        return cls._instances[cls]
class Singleton(metaclass=SingletonMeta):
    def some_business_logic(self):
        """
        Finally, any singleton should define some business logic, which can be
        executed on its instance.
        """
        # ...
if __name__ == "__main__":
    # The client code.
    s1 = Singleton()
    s2 = Singleton()
    if id(s1) == id(s2):
        print("Singleton works, both variables contain the same instance.")
    else:
        print("Singleton failed, variables contain different instances.")

单例模式优缺点

优点:

  • 你可以保证一个类只有一个实例。
  • 你获得了一个指向该实例的全局访问节点。
  • 仅在首次请求单例对象时对其进行初始化。


缺点:


  • 违反了单一职责原则。 该模式同时解决了两个问题。
  • 单例模式可能掩盖不良设计, 比如程序各组件之间相互了解过多等。
  • 该模式在多线程环境下需要进行特殊处理, 避免多个线程多次创建单例对象。
  • 单例的客户端代码单元测试可能会比较困难, 因为许多测试框架以基于继承的方式创建模拟对象。 由于单例类的构造函数是私有的, 而且绝大部分语言无法重写静态方法, 所以你需要想出仔细考虑模拟单例的方法。 要么干脆不编写测试代码, 或者不使用单例模式。
相关文章
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
29 2
|
1月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
7天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
13 2
|
21天前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
29 4
|
25天前
|
设计模式 算法 搜索推荐
Python编程中的设计模式:优雅解决复杂问题的钥匙####
本文将探讨Python编程中几种核心设计模式的应用实例与优势,不涉及具体代码示例,而是聚焦于每种模式背后的设计理念、适用场景及其如何促进代码的可维护性和扩展性。通过理解这些设计模式,开发者可以更加高效地构建软件系统,实现代码复用,提升项目质量。 ####
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
13天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
1月前
|
设计模式 监控 数据库连接
Python编程中的设计模式之美:提升代码质量与可维护性####
【10月更文挑战第21天】 一段简短而富有启发性的开头,引出文章的核心价值所在。 在编程的世界里,设计模式如同建筑师手中的蓝图,为软件的设计和实现提供了一套经过验证的解决方案。本文将深入浅出地探讨Python编程中几种常见的设计模式,通过实例展示它们如何帮助我们构建更加灵活、可扩展且易于维护的代码。 ####
|
1月前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入理解与应用
【10月更文挑战第22天】 在软件开发中,设计模式是解决特定问题的通用解决方案。本文将通过通俗易懂的语言和实例,深入探讨PHP中单例模式的概念、实现方法及其在实际开发中的应用,帮助读者更好地理解和运用这一重要的设计模式。
19 1
|
21天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
23 0