在前面的几篇中,我们已经从理论上理解了设计模式、分类和重构思想。本篇将视角拉回到 Python 本身,看看在实际编写设计模式时,哪些内置工具和标准库最常被用到。
掌握这些工具,能让你用更少的代码实现更清晰的设计模式。
一、abc:抽象类的基石
abc(Abstract Base Class)是 Python 实现设计模式时最重要的基础工具之一。
典型用途
• 策略模式
• 工厂模式
• 模板方法模式
示例:
from abc import ABC, abstractmethodclass Payment(ABC): @abstractmethod def pay(self, amount): pass
作用:
• 强制子类实现指定方法
• 明确“接口契约”
• 提前暴露设计错误
二、typing:让设计更清晰
typing 并不是设计模式本身,但它极大提升了模式的可读性与可维护性。
1. 类型注解
def process(payment: Payment) -> None: payment.pay(100)
阅读代码时,可以快速理解“这里依赖的是抽象,而不是具体实现”。
2. Protocol:轻量级接口
from typing import Protocolclass Payable(Protocol): def pay(self, amount: int) -> None: ...
• 不需要继承
• 只关心“行为是否存在”
• 非常适合策略模式、适配器模式
三、functools:函数级设计模式利器
1. functools.wraps
实现装饰器模式时必不可少:
from functools import wrapsdef log(func): @wraps(func) def wrapper(*args, **kwargs): print("before") return func(*args, **kwargs) return wrapper
保持原函数的名称、文档等元信息。
2. functools.lru_cache
典型的代理 + 缓存模式实现:
from functools import lru_cache@lru_cache(maxsize=128)def get_user(user_id): print("query database") return {"id": user_id}
无需显式写代理类,也能实现缓存代理。
四、enum:状态与策略的好搭档
Enum 在状态模式、策略选择中非常实用。
from enumimport Enumclass OrderStatus(Enum): CREATED = 1 PAID = 2 SHIPPED = 3
• 状态语义清晰
• 避免魔法数字
• 配合状态模式非常自然
五、dataclasses:简化模型对象
在设计模式中,很多类只是数据载体。
from dataclasses import dataclass@dataclassclass User: id: int name: str
• 自动生成 __init__
• 减少样板代码
• 提升模型类可读性
非常适合建造者模式、原型模式中的对象定义。
六、copy:原型模式的基础
import copyobj2 = copy.copy(obj1) # 浅拷贝obj3 = copy.deepcopy(obj1) # 深拷贝
在需要通过“复制已有对象”创建新对象时,原型模式会大量依赖它。
七、contextlib:上下文管理器模式
上下文管理器是 Python 中非常典型的模板方法思想体现。
from contextlib import contextmanager@contextmanagerdef resource(): print("acquire") yield print("release")
• 资源管理
• 日志、锁、事务
• 模板方法模式的函数化实现
八、inspect 与反射机制
Python 的反射能力,在以下模式中非常常见:
• 工厂模式
• 插件式架构
• 依赖注入
import inspectinspect.isclass(obj)inspect.getmembers(module)
让程序在运行时决定“用哪个类、怎么用”。
九、什么时候该用库,什么时候该写模式?
一个实用判断标准:
• 标准库能解决问题 → 优先用库
• 业务逻辑复杂、变化频繁 → 设计模式
• 库解决的是机制,模式解决的是结构
例如:
• 缓存:lru_cache
• 对象创建规则复杂:工厂模式
• 算法可替换:策略模式
十、总结
Python 并不排斥设计模式,反而通过强大的标准库:
• 让模式实现更简洁
• 减少模板代码
• 强化设计表达能力
理解这些工具后,你会发现:很多 Python 风格的设计模式,并不“长得像”传统 UML,但思想完全一致。