🎨 28. 设计模式

本章概述

学习 Python 常用设计模式,提升代码质量和可维护性。 预计学习时间:60 分钟


28.1 单例模式

确保一个类只有一个实例,并提供全局访问点。

实现方式1:new

class Singleton:
    _instance = None
 
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
 
# 使用
s1 = Singleton()
s2 = Singleton()
print(s1 is s2)  # True(同一个实例)

实现方式2:装饰器

def singleton(cls):
    instances = {}
 
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
 
    return wrapper
 
@singleton
class MyClass:
    pass
 
# 使用
m1 = MyClass()
m2 = MyClass()
print(m1 is m2)  # True

实现方式3:元类

class SingletonMeta(type):
    _instances = {}
 
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]
 
class MyClass(metaclass=SingletonMeta):
    pass
 
# 使用
m1 = MyClass()
m2 = MyClass()
print(m1 is m2)  # True

适用场景

  • 配置管理器
  • 日志记录器
  • 数据库连接池
  • 全局状态管理

28.2 工厂模式

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

简单工厂

class Animal:
    def speak(self):
        pass
 
class Dog(Animal):
    def speak(self):
        return "汪汪汪"
 
class Cat(Animal):
    def speak(self):
        return "喵喵喵"
 
class AnimalFactory:
    @staticmethod
    def create_animal(animal_type):
        if animal_type == "dog":
            return Dog()
        elif animal_type == "cat":
            return Cat()
        else:
            raise ValueError(f"未知的动物类型:{animal_type}")
 
# 使用
factory = AnimalFactory()
dog = factory.create_animal("dog")
cat = factory.create_animal("cat")
print(dog.speak())  # 汪汪汪
print(cat.speak())  # 喵喵喵

工厂方法

from abc import ABC, abstractmethod
 
class Animal(ABC):
    @abstractmethod
    def speak(self):
        pass
 
class Dog(Animal):
    def speak(self):
        return "汪汪汪"
 
class Cat(Animal):
    def speak(self):
        return "喵喵喵"
 
class AnimalFactory(ABC):
    @abstractmethod
    def create_animal(self):
        pass
 
class DogFactory(AnimalFactory):
    def create_animal(self):
        return Dog()
 
class CatFactory(AnimalFactory):
    def create_animal(self):
        return Cat()
 
# 使用
dog_factory = DogFactory()
dog = dog_factory.create_animal()
print(dog.speak())  # 汪汪汪

适用场景

  • 对象创建逻辑复杂
  • 需要灵活扩展产品类型
  • 解耦对象创建和使用

28.3 观察者模式

定义对象间的一对多依赖,当一个对象状态改变时,所有依赖它的对象都会收到通知。

实现

class Subject:
    """被观察者(主题)"""
    def __init__(self):
        self._observers = []
 
    def attach(self, observer):
        """添加观察者"""
        if observer not in self._observers:
            self._observers.append(observer)
 
    def detach(self, observer):
        """移除观察者"""
        if observer in self._observers:
            self._observers.remove(observer)
 
    def notify(self):
        """通知所有观察者"""
        for observer in self._observers:
            observer.update(self)
 
class Observer:
    """观察者基类"""
    def update(self, subject):
        pass
 
# 具体的被观察者
class WeatherStation(Subject):
    def __init__(self):
        super().__init__()
        self._temperature = 0
 
    @property
    def temperature(self):
        return self._temperature
 
    @temperature.setter
    def temperature(self, value):
        self._temperature = value
        self.notify()  # 温度变化时通知观察者
 
# 具体的观察者
class PhoneDisplay(Observer):
    def update(self, subject):
        print(f"手机显示:当前温度 {subject.temperature}°C")
 
class TVDisplay(Observer):
    def update(self, subject):
        print(f"电视显示:当前温度 {subject.temperature}°C")
 
# 使用
station = WeatherStation()
 
phone = PhoneDisplay()
tv = TVDisplay()
 
station.attach(phone)
station.attach(tv)
 
station.temperature = 25
# 输出:
# 手机显示:当前温度 25°C
# 电视显示:当前温度 25°C
 
station.temperature = 30
# 输出:
# 手机显示:当前温度 30°C
# 电视显示:当前温度 30°C

适用场景

  • 事件通知系统
  • 消息订阅
  • UI 数据绑定
  • 日志监控

28.4 策略模式

定义一系列算法,把它们封装起来,并且可以互相替换。

实现

from abc import ABC, abstractmethod
 
class SortStrategy(ABC):
    """排序策略基类"""
    @abstractmethod
    def sort(self, data):
        pass
 
class BubbleSort(SortStrategy):
    """冒泡排序"""
    def sort(self, data):
        print("使用冒泡排序")
        # 冒泡排序实现
        return sorted(data)
 
class QuickSort(SortStrategy):
    """快速排序"""
    def sort(self, data):
        print("使用快速排序")
        # 快速排序实现
        return sorted(data)
 
class MergeSort(SortStrategy):
    """归并排序"""
    def sort(self, data):
        print("使用归并排序")
        # 归并排序实现
        return sorted(data)
 
class Sorter:
    """排序器"""
    def __init__(self, strategy):
        self.strategy = strategy
 
    def set_strategy(self, strategy):
        self.strategy = strategy
 
    def sort(self, data):
        return self.strategy.sort(data)
 
# 使用
data = [3, 1, 4, 1, 5, 9, 2, 6]
 
sorter = Sorter(BubbleSort())
result = sorter.sort(data)
print(result)
 
# 切换策略
sorter.set_strategy(QuickSort())
result = sorter.sort(data)
print(result)

适用场景

  • 多种算法可以互换
  • 需要在运行时切换算法
  • 算法有很多条件分支

28.5 装饰器模式

动态地给对象添加额外的职责。

Python 装饰器

Python 的函数装饰器就是装饰器模式的一种实现。 详见 装饰器 章节。


28.6 适配器模式

将一个类的接口转换成客户希望的另一个接口。

实现

class OldSystem:
    """旧系统(接口不兼容)"""
    def old_method(self, data):
        return f"旧系统处理:{data}"
 
class NewSystem:
    """新系统(目标接口)"""
    def new_method(self, request):
        pass
 
class Adapter(NewSystem):
    """适配器"""
    def __init__(self, old_system):
        self.old_system = old_system
 
    def new_method(self, request):
        # 转换请求
        data = request["data"]
        # 调用旧系统
        result = self.old_system.old_method(data)
        # 转换结果
        return {"result": result}
 
# 使用
old = OldSystem()
adapter = Adapter(old)
 
response = adapter.new_method({"data": "测试数据"})
print(response)  # {'result': '旧系统处理:测试数据'}

适用场景

  • 接口不兼容
  • 复用旧代码
  • 第三方库集成

28.7 设计模式总结

创建型模式

模式用途
单例确保只有一个实例
工厂封装对象创建逻辑
建造者分步构建复杂对象
原型通过复制创建对象

结构型模式

模式用途
适配器转换接口
装饰器动态添加功能
代理控制访问
组合树形结构

行为型模式

模式用途
观察者发布订阅
策略算法互换
命令请求封装为对象
迭代器遍历集合
状态状态机

🔗 相关章节


📝 我的笔记

在这里记录你的理解和练习代码

# 你的练习代码
 

✅ 本章检查清单

  • 理解单例模式的实现和应用场景
  • 理解工厂模式的实现和应用场景
  • 理解观察者模式的实现和应用场景
  • 理解策略模式的实现和应用场景
  • 理解适配器模式的实现和应用场景
  • 知道常见的设计模式分类
  • 会根据场景选择合适的设计模式