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 = Nonedef __new__(cls, *args, **kwargs):if not cls._instance:cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)return cls._instancedef __init__(self):if not hasattr(self, 'initialized'):  # 确保只初始化一次  self.value = Noneself.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):@abstractmethoddef sound(self):pass
class Dog(Animal):def sound(self):return "Woof! "
class Cat(Animal):def sound(self):return "Meow! "
class AnimalFactory:@staticmethoddef 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!"