Bootstrap

python常用设计模式,单例模式和工厂设计模式

python常用设计模式,单例和工厂设计模式Demo

单例模式

单例设计模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取该实例。

应用场景:日志记录、线程池、缓存等

优点:

  • 全局访问:提供了一个全局访问点,便于控制实例数量。
  • 资源节约:避免了创建多个对象时的资源浪费。
  • 线程安全:在多线程环境中,可以保证只创建一个实例。
  • 控制实例化:可以控制对象的创建过程。

缺点:

  • 代码耦合:单例模式可能会隐藏一些依赖关系,导致代码耦合。
  • 可测试性差:由于单例模式是全局的,这使得单元测试变得困难。
  • 内存浪费:单例对象在程序的整个生命周期内都占用内存。
  • 滥用:单例模式有时会被滥用,导致程序设计不灵活

方法一:使用模块的全局变量
Python模块是天然的单例,实现单例模式
singleton_module.py

class Singleton:  
    def __init__(self):  
        self.value = None  
  
singleton_instance = Singleton()

在其他地方使用这个单例:

from singleton_module import singleton_instance  
# 使用单例  
singleton_instance.value = 42  
print(singleton_instance.value)  

在这里插入图片描述
方法二:使用类变量
通过类变量来跟踪实例,并在实例化时进行检查

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

    def __init__(self):
        if not hasattr(self, 'initialized'):  # 确保只初始化一次  
            self.value = None
            self.initialized = True

# 使用单例  
singleton1 = Singleton()
singleton2 = Singleton()

singleton1.value = 42
print(singleton2.value)  # 输出: 42  
print(singleton1 is singleton2)  # 输出: True

在这里插入图片描述
方法三:使用装饰器
通过装饰器来实现单例模式

def singleton(cls):  
    instances = {}  
  
    def get_instance(*args, **kwargs):  
        if cls not in instances:  
            instances[cls] = cls(*args, **kwargs)  
        return instances[cls]  
  
    return get_instance  
  
@singleton  
class Singleton:  
    def __init__(self):  
        self.value = None  
  
# 使用单例  
singleton1 = Singleton()  
singleton2 = Singleton()  
  
singleton1.value = 42  
print(singleton2.value)  # 输出: 42  
print(singleton1 is singleton2)  # 输出: True

方法四:使用元类(Metaclass)

class SingletonMeta(type):  
    _instances = {}  
  
    def __call__(cls, *args, **kwargs):  
        if cls not in cls._instances:  
            cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)  
        return cls._instances[cls]  
  
class Singleton(metaclass=SingletonMeta):  
    def __init__(self):  
        self.value = None  
  
# 使用单例  
singleton1 = Singleton()  
singleton2 = Singleton()  
  
singleton1.value = 42  
print(singleton2.value)  # 输出: 42  
print(singleton1 is singleton2)  # 输出: True

最常用和推荐的方法是使用类变量(方法二)和元类(方法四),因为它们在语义上更加清晰和直观

工厂设计模式

定义一个创建对象的接口,让子类决定实例化哪个类

优点:

  • 代码解耦:将对象的创建与使用分离,使得代码更加灵活,易于扩展。
  • 提高可维护性:当需要添加新的产品时,只需要添加一个具体的产品类和相应的具体工厂类即可,无需修改已有的工厂类。
  • 封装性:隐藏了对象创建的细节,调用者只需要知道类型,不需要知道具体的实现。

缺点:

  • 每增加一个产品类别,都需要增加一个产品类和一个工厂类,这可能导致类的数量成倍增加。
  • 系统的抽象程度变得更高,对于简单的情况,可能会增加系统的复杂性。

代码样例:

"""例如,可以使用工厂函数或抽象基类(Abstract Base Classes, ABCs)来实现工厂模式"""
from abc import ABC, abstractmethod
class Animal(ABC):
    @abstractmethod
    def sound(self):
        pass
class Dog(Animal):
    def sound(self):
        return "Woof! "
class Cat(Animal):
    def sound(self):
        return "Meow! "
class AnimalFactory:
    @staticmethod
    def get_animal(animal_type):
        if animal_type == "dog":
            return Dog()
        elif animal_type == "cat":
            return Cat()
        else:
            raise ValueError("Invalid animal type")
 
# 使用工厂模式
factory = AnimalFactory()
dog = factory.create_animal("dog")
cat = factory.create_animal("cat")
print(dog.sound())  # 输出 "Woof!"
print(cat.sound())  # 输出 "Meow!"
;