设计模式概述
学习目标
- 理解设计模式的数学基础与形式化定义
- 掌握设计模式的历史演进与理论框架
- 学会根据问题特征选择合适的设计模式
- 理解Python语言特性对设计模式实现的影响
历史背景与理论演进
设计模式的起源
设计模式的思想源远流长,经历了从建筑学到软件工程的跨学科发展:
| 时期 | 里程碑 | 代表性贡献 |
|---|---|---|
| 1977 | 建筑模式语言 | Christopher Alexander《A Pattern Language》 |
| 1987 | 面向对象模式 | Ward Cunningham与Kent Beck引入软件领域 |
| 1991 | 模式运动 | Bruce Anderson组织首届模式研讨会 |
| 1994 | GoF经典 | 《Design Patterns》出版,确立23种经典模式 |
| 1996 | 模式语言 | PLoP会议,模式目录扩展 |
| 2002 | 企业模式 | Martin Fowler《Patterns of Enterprise Application Architecture》 |
| 2003 | 领域驱动设计 | Eric Evans《Domain-Driven Design》 |
| 2010s | 函数式模式 | 函数式编程范式下的设计模式 |
| 2020s | 云原生模式 | 微服务、容器化、服务网格模式 |
设计模式发展的时间线
1977 ─────────────────────────────────────────────────────────► 2024
│ │
├─ 建筑模式语言 (Alexander)
│
├─ 1987: OOPSLA首次引入软件模式
│
├─ 1994: GoF《设计模式》出版
│ └── 创建型(5) + 结构型(7) + 行为型(11) = 23种
│
├─ 2002: 企业应用架构模式
│
├─ 2010: 函数式设计模式兴起
│
└─ 2020: 云原生与微服务模式形式化定义
设计模式的数学基础
定义0.1(设计模式) 设计模式 $P$ 是一个六元组:
$$P = \langle N, C, S, R, U, A \rangle$$
其中:
- $N$:模式名称(Pattern Name)
- $C$:问题上下文(Context)
- $S$:解决方案结构(Solution Structure)
- $R$:结果与权衡(Consequences)
- $U$:使用场景(Use Cases)
- $A$:相关模式(Related Patterns)
定义0.2(模式语言) 模式语言 $\mathcal{L}$ 是一组相互关联的模式集合:
$$\mathcal{L} = {P_1, P_2, ..., P_n}$$
满足存在关系 $R \subseteq \mathcal{L} \times \mathcal{L}$,表示模式之间的依赖和协作关系。
定义0.3(模式组合) 两个模式 $P_1$ 和 $P_2$ 的组合定义为:
$$P_1 \oplus P_2 = \langle N_{1+2}, C_1 \cap C_2, S_1 \circ S_2, R_1 \cup R_2, U_1 \cup U_2, A_1 \cup A_2 \rangle$$
软件设计的度量
定义0.4(内聚度) 模块内聚度 $C$ 定义为模块内各元素相关程度的度量:
$$C(M) = \frac{\sum_{i,j \in M} r_{ij}}{|M| \cdot (|M| - 1)}$$
其中 $r_{ij}$ 表示元素 $i$ 和 $j$ 的相关度。
定义0.5(耦合度) 模块间耦合度 $D$ 定义为模块间依赖关系的强度:
$$D(M_1, M_2) = \frac{|Dep(M_1, M_2)| + |Dep(M_2, M_1)|}{|M_1| + |M_2|}$$
设计目标:最大化内聚 $C$,最小化耦合 $D$。
抽象层次理论
定义0.6(抽象层次) 软件系统的抽象层次 $L$ 定义为:
$$L = \frac{|Abstract|}{|Concrete| + |Abstract|}$$
其中 $|Abstract|$ 是抽象元素数量,$|Concrete|$ 是具体元素数量。
定理0.1(抽象稳定性) 抽象层次越高,系统稳定性越强:
$$Stability(S) \propto L(S)$$
设计模式的分类体系
三大分类形式化
┌─────────────────────────────────────────────────────────────────────────┐
│ 设计模式分类体系 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 创建型模式 (Creational) │ │
│ │ 定义: 封装对象创建过程,控制实例化时机和方式 │ │
│ │ 形式: create: Context → Object │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Singleton│ │ Factory │ │Abstract │ │ Builder │ │Prototype│ │ │
│ │ │ │ │ Method │ │ Factory │ │ │ │ │ │ │
│ │ │ 唯一实例 │ │ 延迟创建 │ │ 产品族 │ │ 分步构建 │ │ 克隆创建 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 结构型模式 (Structural) │ │
│ │ 定义: 组合类和对象,形成更大的结构 │ │
│ │ 形式: compose: (Component₁ × Component₂) → Structure │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Adapter │ │ Bridge │ │Composite│ │Decorator│ │ Facade │ │ │
│ │ │ 接口转换 │ │ 抽象实现 │ │ 树形结构 │ │ 动态扩展 │ │ 简化接口 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Flyweight│ │ Proxy │ │ │
│ │ │ 共享对象 │ │ 访问控制 │ │ │
│ │ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 行为型模式 (Behavioral) │ │
│ │ 定义: 定义对象间通信和职责分配 │ │
│ │ 形式: interact: (Object₁ × Object₂ × Message) → Behavior │ │
│ ├─────────────────────────────────────────────────────────────────┤ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │Chain of │ │ Command │ │Interpret│ │Iterator │ │ Mediator│ │ │
│ │ │Responsib│ │ 请求封装 │ │ 解释器 │ │ 遍历器 │ │ 中介者 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Memento │ │Observer │ │ State │ │ Strategy│ │Template │ │ │
│ │ │ 状态保存 │ │ 通知机制 │ │ 状态机 │ │ 算法切换 │ │ 算法骨架 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ ┌─────────┐ │ │
│ │ │ Visitor │ │ │
│ │ │ 操作分离 │ │ │
│ │ └─────────┘ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘创建型模式
创建型模式提供了一种在创建对象的同时隐藏创建逻辑的方式:
| 模式 | 意图 | 核心结构 | 适用场景 |
|---|---|---|---|
| 单例模式 | 确保唯一实例 | 私有构造 + 静态实例 | 配置管理、日志、连接池 |
| 工厂方法模式 | 延迟创建到子类 | Creator + Product接口 | 日志系统、数据库驱动 |
| 抽象工厂模式 | 创建产品家族 | AbstractFactory + 产品族 | 跨平台UI、数据库访问 |
| 建造者模式 | 分步构建复杂对象 | Builder + Director | SQL构建器、配置对象 |
| 原型模式 | 克隆创建对象 | clone()方法 | 原型注册表、深拷贝 |
结构型模式
结构型模式关注类和对象的组合:
| 模式 | 意图 | 核心结构 | 适用场景 |
|---|---|---|---|
| 适配器模式 | 接口转换 | Adapter + Target | 第三方库集成、遗留代码 |
| 桥接模式 | 分离抽象与实现 | Abstraction + Implementation | 多维度变化、跨平台 |
| 组合模式 | 树形结构 | Component + Leaf + Composite | 文件系统、组织架构 |
| 装饰器模式 | 动态添加职责 | Component + Decorator | 中间件、流处理 |
| 外观模式 | 简化接口 | Facade | 子系统封装、API简化 |
| 享元模式 | 共享细粒度对象 | Flyweight + FlyweightFactory | 文字编辑、游戏对象 |
| 代理模式 | 控制访问 | Subject + Proxy | 延迟加载、访问控制 |
行为型模式
行为型模式关注对象之间的通信:
| 模式 | 意图 | 核心结构 | 适用场景 |
|---|---|---|---|
| 责任链模式 | 链式处理请求 | Handler + ConcreteHandler | 中间件、审批流程 |
| 命令模式 | 封装请求为对象 | Command + Invoker + Receiver | 撤销操作、任务队列 |
| 解释器模式 | 定义语言文法 | AbstractExpression + Context | DSL、规则引擎 |
| 迭代器模式 | 遍历聚合对象 | Iterator + Aggregate | 自定义集合遍历 |
| 中介者模式 | 集中交互逻辑 | Mediator + Colleague | GUI组件、聊天室 |
| 备忘录模式 | 保存恢复状态 | Memento + Originator + Caretaker | 撤销、存档 |
| 观察者模式 | 一对多依赖通知 | Subject + Observer | 事件系统、数据绑定 |
| 状态模式 | 状态改变行为 | State + Context | 状态机、订单状态 |
| 策略模式 | 可互换算法 | Strategy + Context | 支付方式、排序算法 |
| 模板方法模式 | 算法骨架 | AbstractClass + ConcreteClass | 框架设计、流程模板 |
| 访问者模式 | 分离操作与结构 | Visitor + Element | 编译器、文档处理 |
SOLID设计原则
原则的形式化定义
定义0.7(单一职责原则 SRP) 一个类 $C$ 应该只有一个变化原因 $R$:
$$SRP(C) \iff |{R : R \text{ causes change in } C}| = 1$$
定义0.8(开闭原则 OCP) 软件实体 $E$ 应满足:
$$OCP(E) \iff \forall ext: Extension(ext) \implies \neg Modification(E)$$
定义0.9(里氏替换原则 LSP) 设 $\phi(x)$ 是关于类型 $T$ 的可证明性质:
$$LSP(S, T) \iff \forall o \in S: \phi(o)$$
定义0.10(接口隔离原则 ISP) 客户端 $C$ 不应依赖它不使用的方法:
$$ISP(I) \iff \forall C: deps(C, I) = \bigcap_{m \in used(C, I)} {m}$$
定义0.11(依赖倒置原则 DIP) 高层模块 $H$ 和低层模块 $L$ 都应依赖抽象 $A$:
$$DIP \iff \forall H, L: H \not\to L \land H \to A \land L \to A$$
SOLID原则实现示例
单一职责原则(SRP)
from dataclasses import dataclass
from typing import Optional
from abc import ABC, abstractmethod
@dataclass
class User:
name: str
email: str
class UserRepository:
def __init__(self):
self._users: dict[int, User] = {}
self._next_id = 1
def save(self, user: User) -> int:
user_id = self._next_id
self._users[user_id] = user
self._next_id += 1
return user_id
def find(self, user_id: int) -> Optional[User]:
return self._users.get(user_id)
class UserValidator:
def validate(self, user: User) -> bool:
if not user.name or len(user.name) < 2:
return False
if '@' not in user.email:
return False
return True
class UserNotifier:
def notify(self, user: User, message: str) -> None:
print(f"发送邮件到 {user.email}: {message}")开闭原则(OCP)
from abc import ABC, abstractmethod
from dataclasses import dataclass
@dataclass
class Product:
name: str
price: float
class DiscountStrategy(ABC):
@abstractmethod
def calculate(self, product: Product) -> float:
pass
class NoDiscount(DiscountStrategy):
def calculate(self, product: Product) -> float:
return product.price
class PercentageDiscount(DiscountStrategy):
def __init__(self, percentage: float):
self._percentage = percentage
def calculate(self, product: Product) -> float:
return product.price * (1 - self._percentage / 100)
class PriceCalculator:
def __init__(self, strategy: DiscountStrategy):
self._strategy = strategy
def set_strategy(self, strategy: DiscountStrategy) -> None:
self._strategy = strategy
def calculate(self, product: Product) -> float:
return self._strategy.calculate(product)里氏替换原则(LSP)
from abc import ABC, abstractmethod
class Bird(ABC):
@abstractmethod
def move(self) -> str:
pass
class FlyingBird(Bird):
@abstractmethod
def fly(self) -> str:
pass
def move(self) -> str:
return self.fly()
class SwimmingBird(Bird):
@abstractmethod
def swim(self) -> str:
pass
def move(self) -> str:
return self.swim()
class Sparrow(FlyingBird):
def fly(self) -> str:
return "麻雀飞翔"
class Penguin(SwimmingBird):
def swim(self) -> str:
return "企鹅游泳"
def make_bird_move(bird: Bird) -> str:
return bird.move()接口隔离原则(ISP)
from abc import ABC, abstractmethod
from typing import Protocol
class Printer(Protocol):
def print(self, document: str) -> None: ...
class Scanner(Protocol):
def scan(self) -> str: ...
class Fax(Protocol):
def send_fax(self, number: str, document: str) -> None: ...
class SimplePrinter:
def print(self, document: str) -> None:
print(f"打印: {document}")
class MultiFunctionDevice:
def print(self, document: str) -> None:
print(f"打印: {document}")
def scan(self) -> str:
return "扫描文档"
def send_fax(self, number: str, document: str) -> None:
print(f"发送传真到 {number}: {document}")依赖倒置原则(DIP)
from abc import ABC, abstractmethod
from typing import Protocol
class Database(Protocol):
def save(self, table: str, data: dict) -> int: ...
def find(self, table: str, id: int) -> dict: ...
class MySQLDatabase:
def __init__(self, connection_string: str):
self._connection_string = connection_string
self._data: dict[str, dict[int, dict]] = {}
self._next_id: dict[str, int] = {}
def save(self, table: str, data: dict) -> int:
if table not in self._next_id:
self._next_id[table] = 1
self._data[table] = {}
id = self._next_id[table]
self._data[table][id] = data
self._next_id[table] += 1
return id
def find(self, table: str, id: int) -> dict:
return self._data.get(table, {}).get(id, {})
class UserService:
def __init__(self, database: Database):
self._database = database
def create_user(self, name: str, email: str) -> int:
return self._database.save('users', {'name': name, 'email': email})其他重要原则
迪米特法则(LoD)
定义0.12(迪米特法则) 一个对象 $O$ 应该只与以下对象通信:
$$\forall m \in Methods(O): \forall T \in Types(m): T \in {O, Fields(O), Params(m), Locals(m)}$$
class Department:
def __init__(self, manager_name: str):
self._manager_name = manager_name
def get_manager_name(self) -> str:
return self._manager_name
class Company:
def __init__(self):
self._departments: dict[str, Department] = {}
def add_department(self, name: str, manager: str) -> None:
self._departments[name] = Department(manager)
def get_manager_of_department(self, dept_name: str) -> str:
dept = self._departments.get(dept_name)
return dept.get_manager_name() if dept else ""
class Employee:
def __init__(self, company: Company):
self._company = company
def get_manager(self, department: str) -> str:
return self._company.get_manager_of_department(department)组合复用原则(CRP)
定义0.13(组合复用原则) 优先使用对象组合而非继承:
$$Composition(C) > Inheritance(C) \iff Flexibility(C) > Coupling(C)$$
from typing import Protocol
class Engine(Protocol):
def start(self) -> str: ...
class GasolineEngine:
def start(self) -> str:
return "汽油引擎启动"
class ElectricEngine:
def start(self) -> str:
return "电动引擎启动"
class Car:
def __init__(self, brand: str, engine: Engine):
self._brand = brand
self._engine = engine
def start(self) -> str:
return f"{self._brand}: {self._engine.start()}"设计模式关系图
┌─────────────────────────────────────────────────────────────────────────┐
│ 设计模式关系图 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 创建型模式 │
│ ┌─────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 单例 │ │ 工厂方法 │ │ 抽象工厂 │ │
│ └────┬────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ │ ┌──────┴──────┐ │ │
│ │ │ │ │ │
│ ┌────▼────┐ │ ┌────▼─────┐ │ │
│ │ 原型 │◄───┘ │ 建造者 │◄────┘ │
│ └─────────┘ └──────────┘ │
│ │
│ 结构型模式 │
│ ┌─────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 适配器 │ │ 桥接 │ │ 组合 │ │
│ └────┬────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ │ ┌──────┴──────┐ │ │
│ │ │ │ │ │
│ ┌────▼────┐ │ ┌────▼─────┐ │ │
│ │ 装饰器 │◄───┘ │ 外观 │◄────┘ │
│ └────┬────┘ └──────────┘ │
│ │ │
│ ┌────▼────┐ ┌─────────────┐ │
│ │ 代理 │ │ 享元 │ │
│ └─────────┘ └─────────────┘ │
│ │
│ 行为型模式 │
│ ┌─────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │责任链 │ │ 命令 │ │ 解释器 │ │
│ └─────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 迭代器 │ │ 中介者 │ │ 备忘录 │ │
│ └─────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 观察者 │ │ 状态 │ │ 策略 │ │
│ └─────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────┐ ┌─────────────┐ │
│ │模板方法 │ │ 访问者 │ │
│ └─────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘模式选择决策指南
根据问题类型选择
问题类型分析
│
├── 创建对象
│ ├── 需要唯一实例 → 单例模式
│ ├── 创建过程复杂 → 建造者模式
│ ├── 通过复制创建 → 原型模式
│ ├── 创建产品家族 → 抽象工厂模式
│ └── 延迟创建决策 → 工厂方法模式
│
├── 结构组织
│ ├── 接口不兼容 → 适配器模式
│ ├── 需要动态添加功能 → 装饰器模式
│ ├── 需要简化接口 → 外观模式
│ ├── 需要控制访问 → 代理模式
│ ├── 需要树形结构 → 组合模式
│ ├── 多维度独立变化 → 桥接模式
│ └── 需要共享对象 → 享元模式
│
└── 行为交互
├── 需要通知机制 → 观察者模式
├── 需要切换算法 → 策略模式
├── 需要状态变化 → 状态模式
├── 需要链式处理 → 责任链模式
├── 需要撤销操作 → 命令/备忘录模式
├── 需要遍历集合 → 迭代器模式
├── 需要协调交互 → 中介者模式
├── 需要算法骨架 → 模板方法模式
└── 需要在结构上添加操作 → 访问者模式根据变化点选择
| 变化点 | 推荐模式 | 说明 |
|---|---|---|
| 对象创建方式 | 工厂方法、抽象工厂、原型、建造者 | 封装创建逻辑 |
| 对象结构 | 组合、装饰器、适配器、代理 | 灵活组织结构 |
| 对象行为 | 策略、状态、命令、观察者 | 封装行为变化 |
| 算法实现 | 模板方法、策略 | 复用算法结构 |
| 对象交互 | 中介者、观察者、责任链 | 解耦交互关系 |
| 对象状态 | 备忘录、状态 | 管理状态变化 |
Python与设计模式
Python语言特性对设计模式的影响
| 特性 | 影响的模式 | 具体影响 |
|---|---|---|
| 鸭子类型 | 接口相关模式 | 减少对抽象类的需求 |
| 一等函数 | 策略、命令模式 | 简化实现,无需类包装 |
| 装饰器语法 | 装饰器模式 | 原生语法支持 |
| 元类 | 单例、工厂模式 | 更强大的类创建控制 |
| 模块系统 | 单例模式 | 模块天然是单例 |
| 描述符 | 代理模式 | 属性访问控制 |
| 生成器 | 迭代器模式 | 原生支持迭代协议 |
Pythonic的设计模式实现
from functools import wraps
from typing import Callable, TypeVar, ParamSpec, Generic, Type
from dataclasses import dataclass
from abc import ABC, abstractmethod
import threading
P = ParamSpec('P')
T = TypeVar('T')
# Pythonic单例 - 使用装饰器
def singleton(cls: Callable[P, T]) -> Callable[P, T]:
instances: dict[type, object] = {}
lock = threading.Lock()
@wraps(cls)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
if cls not in instances:
with lock:
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
@singleton
class Database:
def __init__(self, connection_string: str):
self.connection_string = connection_string
# Pythonic策略 - 使用一等函数
from typing import Callable
class PriceCalculator:
def __init__(self, discount_strategy: Callable[[float], float]):
self._strategy = discount_strategy
def calculate(self, price: float) -> float:
return self._strategy(price)
def no_discount(price: float) -> float:
return price
def percentage_discount(percentage: float) -> Callable[[float], float]:
def apply(price: float) -> float:
return price * (1 - percentage / 100)
return apply
# Pythonic迭代器 - 使用生成器
def fibonacci_generator(n: int):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
# Pythonic上下文管理器 - 使用contextlib
from contextlib import contextmanager
@contextmanager
def managed_resource(name: str):
print(f"获取资源: {name}")
try:
yield name
finally:
print(f"释放资源: {name}")反模式警示
常见反模式
| 反模式 | 问题 | 正确做法 |
|---|---|---|
| 上帝类 | 类职责过多 | 应用SRP拆分 |
| 过度设计 | 不必要的抽象 | 应用YAGNI原则 |
| 硬编码 | 魔法数字/字符串 | 使用策略/配置 |
| 循环依赖 | 模块相互依赖 | 应用DIP解耦 |
| 深层继承 | 继承层次过深 | 应用CRP组合 |
| 全局状态 | 滥用全局变量 | 使用依赖注入 |
| 过早优化 | 无测量数据优化 | 先测量后优化 |
模式滥用警示
| 模式 | 滥用场景 | 正确使用 |
|---|---|---|
| 单例 | 所有类都用 | 真正需要唯一实例时 |
| 装饰器 | 简单功能也包装 | 需要动态组合功能时 |
| 观察者 | 所有状态变化 | 真正需要通知机制时 |
| 工厂 | 简单对象创建 | 创建逻辑复杂时 |
| 策略 | 单一算法场景 | 需要切换算法时 |
快速参考卡片
模式速查表
| 类别 | 模式 | 一句话描述 |
|---|---|---|
| 创建型 | 单例 | 全局唯一实例 |
| 创建型 | 工厂方法 | 子类决定创建 |
| 创建型 | 抽象工厂 | 创建产品家族 |
| 创建型 | 建造者 | 分步构建对象 |
| 创建型 | 原型 | 克隆创建对象 |
| 结构型 | 适配器 | 接口转换器 |
| 结构型 | 桥接 | 抽象实现分离 |
| 结构型 | 组合 | 树形结构 |
| 结构型 | 装饰器 | 动态添加功能 |
| 结构型 | 外观 | 简化接口 |
| 结构型 | 享元 | 共享细粒度对象 |
| 结构型 | 代理 | 访问控制 |
| 行为型 | 责任链 | 链式处理 |
| 行为型 | 命令 | 封装请求 |
| 行为型 | 解释器 | 定义语言 |
| 行为型 | 迭代器 | 遍历集合 |
| 行为型 | 中介者 | 集中交互 |
| 行为型 | 备忘录 | 保存状态 |
| 行为型 | 观察者 | 通知机制 |
| 行为型 | 状态 | 状态改变行为 |
| 行为型 | 策略 | 可互换算法 |
| 行为型 | 模板方法 | 算法骨架 |
| 行为型 | 访问者 | 操作分离 |
设计原则检查清单
- [ ] 每个类是否有单一明确的职责?
- [ ] 新功能是否可以通过扩展而非修改实现?
- [ ] 子类是否可以安全替换父类?
- [ ] 接口是否足够精简?
- [ ] 是否依赖抽象而非具体实现?
- [ ] 类之间的耦合是否最小化?
- [ ] 是否优先使用组合而非继承?
- [ ] 代码是否足够简单?
- [ ] 是否存在重复代码?
- [ ] 是否只实现当前需要的功能?
学习建议
学习路径
入门阶段 进阶阶段 高级阶段
│ │ │
├── 理解SOLID原则 ├── 掌握23种经典模式 ├── 模式组合应用
├── 学习简单模式 ├── 理解模式关系 ├── 领域特定模式
│ (单例、策略、外观) │ │
│ ├── 分析开源项目 ├── 架构模式
└── 实践基础示例 └── 重构现有代码 └── 性能优化模式推荐资源
| 类型 | 资源 | 说明 |
|---|---|---|
| 经典著作 | 《设计模式》GoF | 模式圣经 |
| 入门书籍 | 《Head First设计模式》 | 图文并茂 |
| Python专项 | 《流畅的Python》 | Pythonic实现 |
| 企业应用 | 《企业应用架构模式》 | 企业级模式 |
| 领域驱动 | 《领域驱动设计》 | DDD方法论 |
总结
设计模式是软件设计的核心知识体系,它们提供了:
- 通用词汇:开发者之间的共同语言
- 验证方案:经过时间检验的解决方案
- 设计指导:遵循设计原则的最佳实践
- 抽象思维:从具体问题到通用模式的抽象能力
记住:模式是工具,不是目的。好的设计应该解决问题,而不是引入不必要的复杂性。在实际应用中,要根据具体场景灵活选择和组合模式,避免过度设计。
"设计模式不是可以机械套用的公式,而是需要根据具体情境灵活运用的智慧。" — Erich Gamma