跳转至

设计模式

概述

设计模式是针对软件设计中反复出现的问题的可复用解决方案。本文涵盖 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

评论 #