📜  单例方法 – Python设计模式

📅  最后修改于: 2022-05-13 01:55:04.834000             🧑  作者: Mango

单例方法 – Python设计模式

先决条件:单例设计模式 |介绍
单例方法是一种创建设计模式,是我们可用的最简单的设计模式之一。这是一种提供一个且仅一个特定类型的对象的方法。它只涉及一个类来创建方法和指定对象。
单例设计模式可以通过一个非常简单的数据库连接示例来理解。当每个对象创建到数据库的唯一数据库连接时,它将极大地影响项目的成本和费用。所以,建立一个单一的连接总是比建立额外的不相关的连接更好,这可以通过Singleton Design Pattern轻松完成。

python中的单一模式

单例模式

现在让我们看一下单例设计模式的不同实现。

方法1:Monostate/Borg Singleton 设计模式

单例行为可以通过 Borg 的模式来实现,但不是只有一个类的实例,而是有多个实例共享相同的状态。这里我们不关注实例身份的共享,而是关注共享状态。

Python3
# Singleton Borg pattern
class Borg:
 
    # state shared by each instance
    __shared_state = dict()
 
    # constructor method
    def __init__(self):
 
        self.__dict__ = self.__shared_state
        self.state = 'GeeksforGeeks'
 
    def __str__(self):
 
        return self.state
 
# main method
if __name__ == "__main__":
 
    person1 = Borg()    # object of class Borg
    person2 = Borg()    # object of class Borg
    person3 = Borg()    # object of class Borg
 
    person1.state = 'DataStructures' # person1 changed the state
    person2.state = 'Algorithms'     # person2 changed the state
 
    print(person1)    # output --> Algorithms
    print(person2)    # output --> Algorithms
 
    person3.state = 'Geeks'  # person3 changed the
                         # the shared state
 
    print(person1)    # output --> Geeks
    print(person2)    # output --> Geeks
    print(person3)    # output --> Geeks


Python3
# Double Checked Locking singleton pattern
 
 
import threading
 
class SingletonDoubleChecked(object):
 
    # resources shared by each and every
    # instance
 
    __singleton_lock = threading.Lock()
    __singleton_instance = None
 
    # define the classmethod
    @classmethod
    def instance(cls):
 
        # check for the singleton instance
        if not cls.__singleton_instance:
            with cls.__singleton_lock:
                if not cls.__singleton_instance:
                    cls.__singleton_instance = cls()
 
        # return the singleton instance
        return cls.__singleton_instance
 
# main method
if __name__ == '__main__':
 
    # create class X
    class X(SingletonDoubleChecked):
        pass
 
    # create class Y
    class Y(SingletonDoubleChecked):
        pass
 
    A1, A2 = X.instance(), X.instance()
    B1, B2 = Y.instance(), Y.instance()
 
    assert A1 is not B1
    assert A1 is A2
    assert B1 is B2
 
    print('A1 : ', A1)
    print('A2 : ', A2)
    print('B1 : ', B1)
    print('B2 : ', B2)


Python3
# classic implementation of Singleton Design pattern
class Singleton:
 
    __shared_instance = 'GeeksforGeeks'
 
    @staticmethod
    def getInstance():
 
        """Static Access Method"""
        if Singleton.__shared_instance == 'GeeksforGeeks':
            Singleton()
        return Singleton.__shared_instance
 
    def __init__(self):
 
        """virtual private constructor"""
        if Singleton.__shared_instance != 'GeeksforGeeks':
            raise Exception ("This class is a singleton class !")
        else:
            Singleton.__shared_instance = self
 
# main method
if __name__ == "__main__":
 
    # create object of Singleton Class
    obj = Singleton()
    print(obj)
  
    # pick the instance of the class
    obj = Singleton.getInstance()
    print(obj)


输出:

Algorithms
Algorithms
Geeks
Geeks
Geeks
单例设计模式 python

单例设计模式

双重检查锁定单例设计模式

很容易注意到,一旦创建了一个对象,线程的同步就不再有用了,因为现在 object 永远不会等于 None 并且任何操作序列都会导致一致的结果。
因此,当对象等于 None 时,只有我们会在 getInstance 方法上获取Lock

Python3

# Double Checked Locking singleton pattern
 
 
import threading
 
class SingletonDoubleChecked(object):
 
    # resources shared by each and every
    # instance
 
    __singleton_lock = threading.Lock()
    __singleton_instance = None
 
    # define the classmethod
    @classmethod
    def instance(cls):
 
        # check for the singleton instance
        if not cls.__singleton_instance:
            with cls.__singleton_lock:
                if not cls.__singleton_instance:
                    cls.__singleton_instance = cls()
 
        # return the singleton instance
        return cls.__singleton_instance
 
# main method
if __name__ == '__main__':
 
    # create class X
    class X(SingletonDoubleChecked):
        pass
 
    # create class Y
    class Y(SingletonDoubleChecked):
        pass
 
    A1, A2 = X.instance(), X.instance()
    B1, B2 = Y.instance(), Y.instance()
 
    assert A1 is not B1
    assert A1 is A2
    assert B1 is B2
 
    print('A1 : ', A1)
    print('A2 : ', A2)
    print('B1 : ', B1)
    print('B2 : ', B2)

输出:

A1 :  __main__.X object at 0x02EA2590
A2 :  __main__.X object at 0x02EA2590
B1 :  __main__.Y object at 0x02EA25B0
B2 :  __main__.Y object at 0x02EA25B0

单例设计模式的经典实现

在单例设计模式的经典实现中,我们简单地使用静态方法来创建能够返回共享资源的 getInstance 方法。我们还使用所谓的Virtual private Constructor来引发异常,尽管这并不是必需的。

Python3

# classic implementation of Singleton Design pattern
class Singleton:
 
    __shared_instance = 'GeeksforGeeks'
 
    @staticmethod
    def getInstance():
 
        """Static Access Method"""
        if Singleton.__shared_instance == 'GeeksforGeeks':
            Singleton()
        return Singleton.__shared_instance
 
    def __init__(self):
 
        """virtual private constructor"""
        if Singleton.__shared_instance != 'GeeksforGeeks':
            raise Exception ("This class is a singleton class !")
        else:
            Singleton.__shared_instance = self
 
# main method
if __name__ == "__main__":
 
    # create object of Singleton Class
    obj = Singleton()
    print(obj)
  
    # pick the instance of the class
    obj = Singleton.getInstance()
    print(obj)

输出:

__main__.Singleton object at 0x014FFE90
 __main__.Singleton object at 0x014FFE90

类图

单例设计模式类图

单例方法类图

单例类图

使用单例方法的优点:

  1. 初始化:由 Singleton 方法创建的对象只有在第一次被请求时才会被初始化。
  2. 访问对象:我们获得了对对象实例的全局访问权限。
  3. 实例计数:在单例方法中,类不能有多个实例

使用单例方法的缺点:

  1. 多线程环境:在多线程环境中使用单例方法并不容易,因为我们必须注意多线程不会多次创建单例对象。
  2. 单一职责原则:由于 Singleton 方法是一次解决两个问题,它不遵循单一职责原则。
  3. 单元测试过程:当他们将全局状态引入应用程序时,这使得单元测试非常困难。

适用性

  1. 全局变量控制:在特别需要对全局变量进行强控制的项目中,强烈推荐使用单例方法
  2. 日常开发人员使用:单例模式通常用于提供日志记录、缓存、线程池和配置设置,并且经常与工厂设计模式结合使用。

进一步阅读: Java中的单例方法,带有示例的单例设计模式实践