🎨 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 设计模式总结
创建型模式
| 模式 | 用途 |
|---|---|
| 单例 | 确保只有一个实例 |
| 工厂 | 封装对象创建逻辑 |
| 建造者 | 分步构建复杂对象 |
| 原型 | 通过复制创建对象 |
结构型模式
| 模式 | 用途 |
|---|---|
| 适配器 | 转换接口 |
| 装饰器 | 动态添加功能 |
| 代理 | 控制访问 |
| 组合 | 树形结构 |
行为型模式
| 模式 | 用途 |
|---|---|
| 观察者 | 发布订阅 |
| 策略 | 算法互换 |
| 命令 | 请求封装为对象 |
| 迭代器 | 遍历集合 |
| 状态 | 状态机 |
🔗 相关章节
📝 我的笔记
在这里记录你的理解和练习代码
# 你的练习代码
✅ 本章检查清单
- 理解单例模式的实现和应用场景
- 理解工厂模式的实现和应用场景
- 理解观察者模式的实现和应用场景
- 理解策略模式的实现和应用场景
- 理解适配器模式的实现和应用场景
- 知道常见的设计模式分类
- 会根据场景选择合适的设计模式