| 模式类型 | 难度 | 推荐学习顺序 |
|---|---|---|
| 创建型 | ⭐⭐ | 1-2-3-4-5 |
| 结构型 | ⭐⭐⭐ | 1-2-3-4-5-6-7 |
| 行为型 | ⭐⭐⭐⭐ | 1-2-3-4-5-6-7-8-9-10-11 |
需要知道的基础:
创建型模式专注于对象创建机制。
- 01_单例_Singleton - 保证类只有一个实例
- 02_工厂方法_FactoryMethod - 由子类决定实例化哪个类
- 03_抽象工厂_AbstractFactory - 创建一系列相关对象
- 04_建造者_Builder - 分离复杂对象构建与表示
- 05_原型_Prototype - 通过复制原型创建新对象
结构型模式关注对象组合。
- 06_适配器_Adapter - 接口转换
- 07_装饰器_Decorator - 动态添加职责
- 08_代理_Proxy - 控制对象访问
- 09_外观_Facade - 简化复杂子系统
- 10_桥接_Bridge - 分离抽象与实现
- 11_组合_Composite - 树形结构
- 12_享元_Flyweight - 共享对象
行为型模式关注对象交互。
- 13_策略_Strategy - 算法封装
- 14_模板方法_TemplateMethod - 算法骨架
- 15_观察者_Observer - 一对多依赖
- 16_迭代器_Iterator - 统一遍历
- 17_责任链_ChainOfResponsibility - 请求传递
- 18_命令_Command - 请求封装
- 19_备忘录_Memento - 状态保存
- 20_状态_State - 状态影响行为
- 21_访问者_Visitor - 操作分离
- 22_中介者_Mediator - 集中交互
- 23_解释器_Interpreter - 语言解析
GoF(Gang of Four,四人帮)是指 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 四位软件工程专家。他们于1994年出版了《Design Patterns: Elements of Reusable Object-Oriented Software》一书,首次系统性地总结了23种面向对象设计模式。
- 封装变化:找出程序中变化的部分,将其与不变的部分分离
- 面向接口编程:针对抽象类型编程,而不是针对具体实现
- 组合优于继承:优先使用对象组合来实现复用
- 核心思想: 一个类只负责一个职责。
- 通俗理解: 不该管的别管,避免成为什么都做的“上帝类”。
- 优点: 降低类复杂度,提高可读性和可维护性。
- 核心思想: 对扩展开放,对修改关闭。
- 通俗理解: 加新功能时写新代码,尽量不动旧代码。
- 优点: 提高系统稳定性和可维护性,降低修改旧代码的风险。
- 核心思想: 子类必须能完全替换父类,且程序逻辑不变。
- 通俗理解: 凡是用父类的地方,换成子类也得跑得通。
- 优点: 约束继承滥用,确保多态的正确性。
- 核心思想: 客户端不应依赖它不需要的接口。
- 通俗理解: 接口要小而精,不要大而全,避免实现类包含空方法。
- 优点: 降低代码耦合度,提高系统灵活性。
- 核心思想: 面向接口编程,依赖抽象而非具体实现。
- 通俗理解: 电脑主板依赖标准的插槽接口,而不依赖具体的硬件品牌。
- 优点: 极大降低类间耦合,便于替换和维护。
- 核心思想: 一个对象应对其他对象有最少的了解。
- 通俗理解: 只与直接的朋友(自身、成员、参数、内部创建对象)通信,不和“陌生人”说话。
- 优点: 降低类间耦合,提高系统可读性和稳定性。
- 潜在缺点: 可能需要创建大量中介类,增加系统复杂度。
- 核心思想: 尽量使用对象组合(has-a)而不是继承(is-a)来达到复用目的。
- 通俗理解: 如果你需要一辆车,组合的思路是“我有一辆车”(买零件组装),而不是“我是一辆车”(自己造所有零件)。
- 优点: 降低耦合度,提高灵活性(可在运行时动态替换),不破坏封装。
- 风险提示: 继承容易导致基类脆弱问题(父类修改影响所有子类)。
| 设计原则 | 相关设计模式 |
|---|---|
| 单一职责 | 策略模式、命令模式、装饰器模式 |
| 开闭原则 | 策略模式、装饰器模式、访问者模式 |
| 里氏替换 | 策略模式、模板方法模式、状态模式 |
| 接口隔离 | 装饰器模式、代理模式、迭代器模式 |
| 依赖倒置 | 工厂方法模式、抽象工厂模式、依赖注入 |
| 迪米特法则 | 中介者模式、外观模式 |
| 合成复用 | 组合模式、装饰器模式、代理模式 |
接口是设计模式的核心组成部分,主要作用包括:
- 定义抽象层:通过接口定义行为规范,将"做什么"与"怎么做"分离
- 解耦实现:客户端依赖接口而非具体实现,便于替换和扩展
- 实现多态:同一接口可以有多种实现,运行时动态选择
- 约束行为:确保实现类提供特定的方法和能力
| 接口类型 | 相关设计模式 | 说明 |
|---|---|---|
| 产品接口 | 工厂方法、抽象工厂 | 定义产品对象的统一接口 |
| 策略接口 | 策略模式、状态模式 | 封装可互换的算法 |
| 迭代器接口 | 迭代器模式 | 统一遍历不同集合的方式 |
| 命令接口 | 命令模式 | 封装请求为对象 |
| 观察者接口 | 观察者模式 | 定义通知机制 |
| 组件接口 | 组合模式、装饰器模式 | 统一组件行为 |
| 访问者接口 | 访问者模式 | 定义对元素的操作 |
| 中介者接口 | 中介者模式 | 定义对象间通信 |
| 适配器接口 | 适配器模式 | 统一不同接口 |
| 代理接口 | 代理模式 | 控制对对象的访问 |
Python 使用多种方式实现接口概念:
from abc import ABC, abstractmethod
class Drawable(ABC):
@abstractmethod
def draw(self):
pass
class Circle(Drawable):
def draw(self):
print("绘制圆形")
class Rectangle(Drawable):
def draw(self):
print("绘制矩形")from typing import Protocol
class Drawable(Protocol):
def draw(self) -> None:
...
# 无需显式继承,结构兼容即可
class Circle:
def draw(self):
print("绘制圆形")# 只需对象具有 draw 方法即可
def draw_shape(shape):
shape.draw() # 不需要显式接口声明# 策略模式:策略接口
class PaymentStrategy(ABC):
@abstractmethod
def pay(self, amount):
pass
# 状态模式:状态接口
class State(ABC):
@abstractmethod
def handle(self, context):
pass
# 命令模式:命令接口
class Command(ABC):
@abstractmethod
def execute(self):
pass
# 观察者模式:观察者接口
class Observer(ABC):
@abstractmethod
def update(self, data):
pass
# 迭代器模式:迭代器接口
class Iterator(ABC):
@abstractmethod
def __next__(self):
pass
@abstractmethod
def __iter__(self):
pass- 保持接口小而专注:遵循接口隔离原则
- 使用抽象类而非具体类:依赖抽象而非具体
- 避免肥接口:将大接口拆分为小接口
- 为接口命名要描述行为:使用动词或形容词
- 考虑未来扩展:接口应具有通用性
- 阅读笔记 - 理解概念和原理
- 入门级代码 - 掌握核心思想
- 简单级代码 - 理解完整结构
- 中级代码 - 了解实际应用
- 高级代码 - 生产级实现
每个模式目录下包含 4 个代码文件:
01_beginner.py- 入门级(约15行)02_simple.py- 简单级(约30行)03_intermediate.py- 中级(约60行)04_advanced.py- 高级(约100行)