学习指南
High Contrast
Dark Mode
Light Mode
Sepia
Forest
6 min read1,292 words

学习指南

设计模式不是靠死记硬背掌握的,而是通过理解、实践和思考逐步建立的设计思维。本章为你提供高效学习设计模式的方法和技巧。

学习路径

graph LR A[第1步
理解概念] --> B[第2步
查看示例] B --> C[第3步
动手实践] C --> D[第4步
分析应用场景] D --> E[第5步
应用到项目] E --> F[第6步
反思总结] A --> A1[模式解决的问题] B --> B1[标准实现方式] C --> C1[修改、扩展、重写] D --> D1[何时用、何时不该用] E --> E1[识别使用机会] F --> F1[记录笔记和心得] style A fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style B fill:#e3f2fd,stroke:#1976d2,stroke-width:2px style C fill:#fff9c4,stroke:#f9a825,stroke-width:2px style D fill:#fff9c4,stroke:#f9a825,stroke-width:2px style E fill:#c8e6c9,stroke:#43a047,stroke-width:2px style F fill:#a5d6a7,stroke:#43a047,stroke-width:2px

第一步:理解核心概念

问自己三个问题

学习每个设计模式时,都要问自己:

  1. 这个模式解决什么问题?
  2. 不使用这个模式会怎样?
  3. 这个模式的核心思想是什么?

示例:单例模式

问题 答案
解决什么问题? 确保一个类只有一个实例,并提供全局访问点
不用会怎样? 多个实例可能导致状态不一致、资源浪费
核心思想是什么? 控制实例化过程,提供唯一访问方式

第二步:查看标准实现

代码示例

# 单例模式的标准实现
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,两个变量指向同一个实例

类图理解

用类图或流程图帮助理解模式结构:

classDiagram class Singleton { -instance: Singleton +getInstance() Singleton } note for Singleton "单例模式确保一个类只有一个实例"

第三步:动手实践

练习1:修改示例

# 练习:给单例模式添加初始化参数
class ConfigSingleton:
_instance = None
_initialized = False
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, config_file=None):
if not self._initialized:
self.config = {}
if config_file:
self.load_config(config_file)
self._initialized = True
def load_config(self, file):
self.config = {"from": file}
def get(self, key):
return self.config.get(key)
# 测试
config1 = ConfigSingleton("app.conf")
config2 = ConfigSingleton("another.conf")  # 不会重新初始化
print(config1.get("from"))  # app.conf
print(config2.get("from"))  # app.conf(同一个实例)

练习2:识别模式

阅读现有代码,尝试识别使用了哪些设计模式:

# 这段代码用了什么模式?
from abc import ABC, abstractmethod
class SortStrategy(ABC):
@abstractmethod
def sort(self, data):
pass
class BubbleSort(SortStrategy):
def sort(self, data):
return sorted(data)
class QuickSort(SortStrategy):
def sort(self, data):
return sorted(data)
class Sorter:
def __init__(self, strategy: SortStrategy):
self.strategy = strategy
def perform_sort(self, data):
return self.strategy.sort(data)

答案:策略模式(Strategy Pattern)

第四步:分析应用场景

使用场景分析

场景 是否适合单例模式 理由
数据库连接池 ✅ 适合 需要全局唯一,避免重复连接
工具类(如Math) ❌ 不适合 可以用静态方法,无需实例
配置管理器 ✅ 适合 需要全局唯一,缓存配置
日志记录器 ✅ 适合 避免文件冲突,统一输出

反例:误用设计模式

# ❌ 误用单例模式
class Calculator:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def add(self, x, y):
return x + y
# 问题:Calculator根本不需要单例!
# 应该用普通类或静态方法
# ✅ 正确做法
class Calculator:
@staticmethod
def add(x, y):
return x + y

第五步:应用到项目

在实际代码中识别机会

当你遇到以下情况时,考虑使用设计模式:

问题信号 可能的设计模式
代码中大量 if-elif-elseswitch-case 策略模式、状态模式
需要在不修改原代码的情况下扩展功能 装饰器模式
对象创建逻辑复杂 工厂模式、建造者模式
多个类需要共享行为 模板方法模式
需要通知多个对象某个事件 观察者模式

重构示例

重构前

class NotificationService:
"""通知服务 - 大量if-elif"""
def send(self, message, channel):
if channel == "email":
self._send_email(message)
elif channel == "sms":
self._send_sms(message)
elif channel == "push":
self._send_push(message)
elif channel == "wechat":
self._send_wechat(message)
# ... 更多类型
def _send_email(self, message):
print(f"邮件:{message}")
def _send_sms(self, message):
print(f"短信:{message}")
def _send_push(self, message):
print(f"推送:{message}")
def _send_wechat(self, message):
print(f"微信:{message}")

重构后(使用策略模式)

from abc import ABC, abstractmethod
class NotificationStrategy(ABC):
@abstractmethod
def send(self, message):
pass
class EmailNotification(NotificationStrategy):
def send(self, message):
print(f"邮件:{message}")
class SMSNotification(NotificationStrategy):
def send(self, message):
print(f"短信:{message}")
class PushNotification(NotificationStrategy):
def send(self, message):
print(f"推送:{message}")
class WeChatNotification(NotificationStrategy):
def send(self, message):
print(f"微信:{message}")
class NotificationService:
def __init__(self, strategy: NotificationStrategy):
self.strategy = strategy
def send(self, message):
self.strategy.send(message)
# 使用:轻松扩展新渠道
class SlackNotification(NotificationStrategy):
def send(self, message):
print(f"Slack:{message}")
email_service = NotificationService(EmailNotification())
slack_service = NotificationService(SlackNotification())
email_service.send("你好")   # 邮件:你好
slack_service.send("你好")   # Slack:你好

第六步:反思总结

学习笔记模板

为每个设计模式创建一份学习笔记:

# 模式名称
## 核心概念
- 这个模式解决什么问题?
- 核心思想是什么?
## 标准实现
[代码示例]
## 适用场景
- ✅ 场景1
- ✅ 场景2
## 不适用场景
- ❌ 场景1
- ❌ 场景2
## 实际应用
[在项目中应用的例子]
## 相关模式
- 与XX模式的区别
- 可以与XX模式组合使用

学习技巧

技巧1:对比学习

对比相似的模式,理解差异:

模式 目的 何时使用
工厂方法 创建对象 不知道具体类型
抽象工厂 创建对象族 需要创建相关对象
建造者 创建复杂对象 需要分步骤创建
原型 复制对象 创建成本高

技巧2:从简单开始

先用最简单的实现,理解核心思想:

# 单例模式 - 最简单版本
class Singleton:
instance = None
def get_instance():
if Singleton.instance is None:
Singleton.instance = Singleton()
return Singleton.instance
# 等理解了再加线程安全等其他考虑

技巧3:查看源码

学习Python标准库和框架中的模式应用:

# Python标准库中的设计模式
# 迭代器模式 - built-in
for item in [1, 2, 3]:
print(item)
# 装饰器模式 - @decorator语法
@log_calls
def my_function():
pass
# 单例模式 - sys.modules
import sys
sys.modules['my_module'] = my_module  # 模块只加载一次

技巧4:画图理解

用图示帮助理解模式关系:

graph TB A[创建型模式] --> B[单例] A --> C[工厂方法] A --> D[抽象工厂] A --> E[建造者] F[创建方式] --> G[简单对象] F --> H[复杂对象] F --> I[对象族] G --> C H --> E I --> D D --> B style A fill:#ede7f6,stroke:#5e35b1,stroke-width:3px

常见错误

❌ 错误1:过度设计

# 为了用模式而用模式
class SimpleCalculator:
def calculate(self, operation, x, y):
if operation == "add":
return x + y
elif operation == "subtract":
return x - y
# 不要用策略模式重构!简单直接更好

❌ 错误2:死记硬背

不要只记住代码实现,要理解原理。

错误做法: - 背诵单例模式的代码 - 背诵UML类图

正确做法: - 理解单例模式解决的问题 - 知道何时使用单例模式 - 能自己推导出实现方式

❌ 错误3:忽视语言特性

Python有独特的语法糖,可以简化模式实现:

# 传统装饰器模式
class LoggingDecorator:
def __init__(self, component):
self.component = component
def operation(self):
print("开始执行")
result = self.component.operation()
print("执行完成")
return result
# Python方式:装饰器语法
@log_calls
def operation():
pass

学习资源

推荐书籍

  1. 《设计模式:可复用面向对象软件的基础》(GoF四人组) - 设计模式的圣经 - 23种经典模式

  2. 《Head First 设计模式》 - 适合初学者 - 图文并茂,生动有趣

  3. 《Python设计模式》 - Python-specific - 实用性强

推荐网站

学习计划

基础阶段(第1-2周)

进阶阶段(第3-4周)

实践阶段(第5-6周)

本章要点


恭喜完成前置知识部分!

下一步创建型模式 开始学习第一个设计模式 🚀