设计模式
概述
设计模式是针对软件设计中反复出现的问题的可复用解决方案。本文涵盖 SOLID 原则和 GoF(Gang of Four)经典设计模式中最常用的部分。
1. SOLID 原则
| 原则 | 全称 | 含义 |
|---|---|---|
| S | Single Responsibility | 一个类只负责一件事 |
| O | Open/Closed | 对扩展开放,对修改关闭 |
| L | Liskov Substitution | 子类可以替换父类 |
| I | Interface Segregation | 接口应该小而专一 |
| D | Dependency Inversion | 依赖抽象,而非具体实现 |
示例:依赖倒置
# 违反 DIP
class MySQLDatabase:
def query(self, sql): ...
class UserService:
def __init__(self):
self.db = MySQLDatabase() # 直接依赖具体实现
# 遵循 DIP
from abc import ABC, abstractmethod
class Database(ABC):
@abstractmethod
def query(self, sql): ...
class MySQLDatabase(Database):
def query(self, sql): ...
class PostgresDatabase(Database):
def query(self, sql): ...
class UserService:
def __init__(self, db: Database): # 依赖抽象
self.db = db
2. 创建型模式(Creational)
2.1 单例模式(Singleton)
确保一个类只有一个实例。
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
# 线程安全版本
import threading
class ThreadSafeSingleton:
_instance = None
_lock = threading.Lock()
def __new__(cls):
if cls._instance is None:
with cls._lock:
if cls._instance is None: # 双重检查
cls._instance = super().__new__(cls)
return cls._instance
使用场景:数据库连接池、日志器、配置管理。
2.2 工厂模式(Factory)
将对象创建委托给工厂方法。
class Animal(ABC):
@abstractmethod
def speak(self): ...
class Dog(Animal):
def speak(self): return "Woof!"
class Cat(Animal):
def speak(self): return "Meow!"
class AnimalFactory:
@staticmethod
def create(animal_type: str) -> Animal:
factories = {
"dog": Dog,
"cat": Cat,
}
if animal_type not in factories:
raise ValueError(f"Unknown animal: {animal_type}")
return factories[animal_type]()
animal = AnimalFactory.create("dog")
print(animal.speak()) # Woof!
使用场景:根据配置/输入创建不同类型的对象。
2.3 建造者模式(Builder)
逐步构建复杂对象。
class QueryBuilder:
def __init__(self):
self._table = None
self._conditions = []
self._order_by = None
self._limit = None
def table(self, name):
self._table = name
return self
def where(self, condition):
self._conditions.append(condition)
return self
def order(self, field):
self._order_by = field
return self
def limit(self, n):
self._limit = n
return self
def build(self):
sql = f"SELECT * FROM {self._table}"
if self._conditions:
sql += " WHERE " + " AND ".join(self._conditions)
if self._order_by:
sql += f" ORDER BY {self._order_by}"
if self._limit:
sql += f" LIMIT {self._limit}"
return sql
query = (QueryBuilder()
.table("users")
.where("age > 18")
.where("active = 1")
.order("created_at DESC")
.limit(10)
.build())
# SELECT * FROM users WHERE age > 18 AND active = 1 ORDER BY created_at DESC LIMIT 10
使用场景:构建复杂配置、SQL 查询、HTTP 请求。
2.4 原型模式(Prototype)
通过克隆现有对象创建新对象。
import copy
class Prototype:
def clone(self):
return copy.deepcopy(self)
class GameUnit(Prototype):
def __init__(self, name, hp, attack):
self.name = name
self.hp = hp
self.attack = attack
template = GameUnit("Warrior", 100, 15)
unit1 = template.clone()
unit1.name = "Warrior_1"
3. 结构型模式(Structural)
3.1 适配器模式(Adapter)
将一个接口转换为客户端期望的另一个接口。
# 已有的旧接口
class OldPaymentSystem:
def make_payment(self, amount_in_cents):
print(f"Paid {amount_in_cents} cents")
# 新接口
class PaymentProcessor(ABC):
@abstractmethod
def pay(self, amount_in_dollars): ...
# 适配器
class PaymentAdapter(PaymentProcessor):
def __init__(self, old_system: OldPaymentSystem):
self.old_system = old_system
def pay(self, amount_in_dollars):
self.old_system.make_payment(int(amount_in_dollars * 100))
adapter = PaymentAdapter(OldPaymentSystem())
adapter.pay(9.99) # Paid 999 cents
3.2 装饰器模式(Decorator)
动态为对象添加职责。
class DataSource(ABC):
@abstractmethod
def write(self, data: str): ...
@abstractmethod
def read(self) -> str: ...
class FileDataSource(DataSource):
def __init__(self, filename):
self.filename = filename
def write(self, data):
with open(self.filename, 'w') as f:
f.write(data)
def read(self):
with open(self.filename) as f:
return f.read()
class EncryptionDecorator(DataSource):
def __init__(self, source: DataSource):
self.source = source
def write(self, data):
encrypted = data[::-1] # 简化的"加密"
self.source.write(encrypted)
def read(self):
return self.source.read()[::-1]
class CompressionDecorator(DataSource):
def __init__(self, source: DataSource):
self.source = source
def write(self, data):
import zlib
self.source.write(zlib.compress(data.encode()).hex())
def read(self):
import zlib
return zlib.decompress(bytes.fromhex(self.source.read())).decode()
# 组合使用
source = EncryptionDecorator(CompressionDecorator(FileDataSource("data.txt")))
source.write("Hello, World!")
3.3 代理模式(Proxy)
class ImageProxy:
"""延迟加载代理"""
def __init__(self, filename):
self.filename = filename
self._real_image = None
def display(self):
if self._real_image is None:
print(f"Loading {self.filename}...")
self._real_image = self._load_image()
self._real_image.display()
def _load_image(self):
return RealImage(self.filename)
3.4 外观模式(Facade)
为复杂子系统提供简单接口。
class VideoConverter:
"""外观:隐藏复杂的视频转换子系统"""
def convert(self, filename, format):
file = VideoFile(filename)
codec = CodecFactory.extract(file)
if format == "mp4":
result = MPEG4Compressor().compress(codec)
elif format == "avi":
result = AVICompressor().compress(codec)
return result
# 客户端只需要:
converter = VideoConverter()
mp4 = converter.convert("video.ogg", "mp4")
4. 行为型模式(Behavioral)
4.1 观察者模式(Observer)
对象状态变化时自动通知依赖者。
class EventEmitter:
def __init__(self):
self._listeners = {}
def on(self, event, callback):
self._listeners.setdefault(event, []).append(callback)
def emit(self, event, *args, **kwargs):
for callback in self._listeners.get(event, []):
callback(*args, **kwargs)
# 使用
emitter = EventEmitter()
emitter.on("user_created", lambda user: print(f"Welcome {user}!"))
emitter.on("user_created", lambda user: send_email(user))
emitter.emit("user_created", "Alice")
4.2 策略模式(Strategy)
定义算法族,使它们可以互换。
class SortStrategy(ABC):
@abstractmethod
def sort(self, data: list) -> list: ...
class QuickSort(SortStrategy):
def sort(self, data):
if len(data) <= 1: return data
pivot = data[0]
left = [x for x in data[1:] if x <= pivot]
right = [x for x in data[1:] if x > pivot]
return self.sort(left) + [pivot] + self.sort(right)
class MergeSort(SortStrategy):
def sort(self, data):
# merge sort 实现
...
class Sorter:
def __init__(self, strategy: SortStrategy):
self.strategy = strategy
def sort(self, data):
return self.strategy.sort(data)
# 运行时切换策略
sorter = Sorter(QuickSort())
result = sorter.sort([3, 1, 4, 1, 5])
4.3 命令模式(Command)
将请求封装为对象,支持撤销/重做。
class Command(ABC):
@abstractmethod
def execute(self): ...
@abstractmethod
def undo(self): ...
class InsertTextCommand(Command):
def __init__(self, editor, text, position):
self.editor = editor
self.text = text
self.position = position
def execute(self):
self.editor.insert(self.position, self.text)
def undo(self):
self.editor.delete(self.position, len(self.text))
class CommandHistory:
def __init__(self):
self._history = []
def execute(self, command):
command.execute()
self._history.append(command)
def undo(self):
if self._history:
command = self._history.pop()
command.undo()
4.4 迭代器模式(Iterator)
class BinaryTree:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def __iter__(self):
"""中序遍历迭代器"""
if self.left:
yield from self.left
yield self.value
if self.right:
yield from self.right
tree = BinaryTree(2, BinaryTree(1), BinaryTree(3))
for val in tree:
print(val) # 1, 2, 3
4.5 状态模式(State)
class State(ABC):
@abstractmethod
def handle(self, context): ...
class IdleState(State):
def handle(self, context):
print("Starting...")
context.state = RunningState()
class RunningState(State):
def handle(self, context):
print("Pausing...")
context.state = PausedState()
class PausedState(State):
def handle(self, context):
print("Resuming...")
context.state = RunningState()
class Player:
def __init__(self):
self.state = IdleState()
def press_button(self):
self.state.handle(self)
5. 反模式(Anti-patterns)
| 反模式 | 描述 | 改进 |
|---|---|---|
| God Object | 一个类承担过多职责 | 拆分为多个类(SRP) |
| Spaghetti Code | 代码结构混乱,缺少模块化 | 引入清晰的模块/层次 |
| Golden Hammer | 对所有问题使用同一技术 | 根据问题选择合适方案 |
| Premature Optimization | 过早优化不重要的部分 | 先 profile,再优化瓶颈 |
| Copy-Paste | 大量重复代码 | 提取公共方法/基类 |
| Magic Numbers | 代码中硬编码数字 | 使用命名常量 |
| Singleton Abuse | 过度使用单例 | 依赖注入 |
6. 设计模式选择指南
需要创建对象?
├── 一种类型,控制实例数量 → Singleton
├── 多种类型,根据条件创建 → Factory
├── 对象构建过程复杂 → Builder
└── 从模板复制 → Prototype
需要组合/包装对象?
├── 接口不兼容 → Adapter
├── 动态添加功能 → Decorator
├── 控制访问 → Proxy
└── 简化复杂接口 → Facade
需要管理对象间交互?
├── 一对多通知 → Observer
├── 算法可切换 → Strategy
├── 支持撤销 → Command
├── 状态驱动行为 → State
└── 统一遍历方式 → Iterator
与其他主题的关系
- 参见 软件工程概述,理解设计模式在整个软件工程主线中的位置
- 参见 系统设计,理解局部对象结构与系统级边界、职责拆分之间的关系
- 参见 全栈开发,理解设计模式如何在 Web 应用和服务层组织中落地
- 参见 测试与质量保障,理解良好设计如何降低测试与回归成本
参考文献
- "Design Patterns: Elements of Reusable Object-Oriented Software" - GoF
- "Head First Design Patterns" - Freeman & Robson
- "Clean Architecture" - Robert C. Martin
- Refactoring Guru: https://refactoring.guru/design-patterns