设计模式
设计模式
设计模式是软件开发中经过验证的、可复用的解决方案模板,源自 GoF(Gang of Four)的经典著作《设计模式:可复用面向对象软件的基础》。
为什么需要设计模式
- 复用成熟经验,避免重复设计
- 提供通用词汇,便于团队沟通
- 提高代码可读性、可维护性、可扩展性
- 降低系统耦合,增强灵活性
设计模式分类(23 种 GoF 模式)
创建型(5): 工厂方法、抽象工厂、单例、建造者、原型
结构型(7): 适配器、装饰器、代理、外观、桥接、组合、享元
行为型(11): 观察者、策略、命令、模板方法、迭代器、
责任链、状态、访问者、中介者、备忘录、解释器
设计原则
开闭原则: 对扩展开放,对修改关闭
单一职责: 一个类只做一件事
里氏替换: 子类可替换父类
接口隔离: 用多个专门接口替代大接口
依赖倒置: 依赖抽象,不依赖具体实现
最少知识: 不与陌生人通信
本教程
后续章节用 Python 实现 23 种经典设计模式,每种都附完整代码与适用场景。
Python 设计模式
Python 设计模式
Python 的鸭子类型、动态特性与一等函数让设计模式的实现更简洁,有些甚至"天然内建"。
Python 特性与模式
Python 特性 相关模式
动态类型 适配器更简单(无需接口)
一等函数 策略/命令可用函数实现
装饰器语法糖 装饰器模式天然支持
上下文管理器 模板方法/资源管理
迭代器协议 迭代器模式内建
元类 单例/工厂的进阶手段
示例:用函数实现策略模式
# 传统类实现
class Strategy:
def execute(self, data): raise NotImplementedError
# Python 函数式:策略就是普通函数
def strategy_a(data):
return sorted(data)
def strategy_b(data):
return sorted(data, reverse=True)
def process(strategy, data):
return strategy(data)
process(strategy_a, [3, 1, 2]) # [1, 2, 3]
学习建议
- 先理解模式意图,再记结构
- 用 Python 简化实现,不照搬 Java 样板
- 避免过度设计:模式是为了解决问题
Python 工厂模式
Python 工厂模式
工厂模式将对象创建与使用分离,客户端无需关心具体类。
简单工厂(非 GoF 但常用)
class Dog:
def speak(self): return "汪汪"
class Cat:
def speak(self): return "喵喵"
class AnimalFactory:
@staticmethod
def create(animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
raise ValueError("未知类型")
# 使用
animal = AnimalFactory.create("dog")
print(animal.speak()) # 汪汪
工厂方法模式
from abc import ABC, abstractmethod
class Creator(ABC):
@abstractmethod
def create(self): ...
def do_something(self):
obj = self.create()
return obj.operate()
class DogCreator(Creator):
def create(self):
return Dog()
class CatCreator(Creator):
def create(self):
return Cat()
抽象工厂模式
class AnimalFactory(ABC):
@abstractmethod
def create_pet(self): ...
@abstractmethod
def create_wild(self): ...
class DogFactory(AnimalFactory):
def create_pet(self): return Dog()
def create_wild(self): return Wolf()
适用场景
对象创建逻辑复杂(参数化创建)
希望把创建代码集中管理
需要替换具体产品而不改客户端Python 单例模式
Python 单例模式
单例确保一个类只有一个实例,常用于配置、连接池、日志等全局对象。
方式一:__new__ 实现
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
self.value = 0
a = Singleton()
b = Singleton()
print(a is b) # True
方式二:装饰器
def singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class Config:
def __init__(self):
self.retries = 3
c1 = Config()
c2 = Config()
print(c1 is c2) # True
方式三:模块级单例(Pythonic)
# config.py
class Config:
...
config = Config() # 模块天然单例
# 使用
from config import config
注意事项
1. 单例在多线程下要注意线程安全(加锁)
2. 单例增加全局状态,慎用,测试困难
3. 依赖注入常是更优替代方案Python 建造者模式
Python 建造者模式
建造者模式将复杂对象的构建过程与表示分离,支持分步构建。
传统实现
class Computer:
def __init__(self):
self.cpu = None
self.ram = None
self.storage = None
self.gpu = None
def __str__(self):
return f"CPU:{self.cpu} RAM:{self.ram} 存储:{self.storage} GPU:{self.gpu}"
class ComputerBuilder:
def __init__(self):
self.computer = Computer()
def set_cpu(self, cpu):
self.computer.cpu = cpu
return self # 支持链式
def set_ram(self, ram):
self.computer.ram = ram
return self
def set_storage(self, storage):
self.computer.storage = storage
return self
def build(self):
return self.computer
# 使用
pc = (ComputerBuilder()
.set_cpu("i9")
.set_ram("32GB")
.set_storage("1TB SSD")
.build())
print(pc)
链式调用(流畅接口)
builder = ComputerBuilder()
pc = (builder.set_cpu("i5")
.set_ram("16GB")
.build())
适用场景
对象有大量可选参数
构建步骤固定但实现可变化
希望避免构造器参数过多
Python 简化
# 参数少时直接用 dataclass 更简单
from dataclasses import dataclass
@dataclass
class Computer:
cpu: str = "默认"
ram: str = "8GB"
storage: str = "256GB"Python 原型模式
Python 原型模式
原型模式通过复制现有对象创建新对象,避免重新构造,利用 copy 模块实现。
浅拷贝与深拷贝
import copy
class Prototype:
def __init__(self, name, data=None):
self.name = name
self.data = data if data else []
def clone(self, shallow=True):
if shallow:
return copy.copy(self) # 浅拷贝
return copy.deepcopy(self) # 深拷贝
original = Prototype("原始", [1, 2, 3])
shallow = original.clone()
deep = original.clone(shallow=False)
original.data.append(4)
print(shallow.data) # [1, 2, 3, 4] 浅拷贝共享引用!
print(deep.data) # [1, 2, 3] 深拷贝独立
原型注册表
class PrototypeRegistry:
def __init__(self):
self._prototypes = {}
def register(self, name, prototype):
self._prototypes[name] = prototype
def clone(self, name, **kwargs):
proto = self._prototypes[name]
clone = copy.deepcopy(proto)
clone.__dict__.update(kwargs) # 覆盖属性
return clone
适用场景
对象创建成本高(数据库查询、复杂计算)
对象有很多相似变体
避免大量工厂类
注意
默认 copy.copy 是浅拷贝,嵌套对象共享
自定义 __copy__/__deepcopy__ 控制拷贝行为Python 适配器模式
Python 适配器模式
适配器让接口不兼容的类可以协作,Python 的动态特性让它实现非常自然。
类适配器
class Usb:
def connect_usb(self):
return "USB 连接"
class TypeC:
def connect_typec(self):
return "Type-C 连接"
# 适配器:把 TypeC 适配成 Usb 接口
class TypeCAdapter(Usb):
def __init__(self, typec):
self.typec = typec
def connect_usb(self):
return self.typec.connect_typec()
# 使用
adapter = TypeCAdapter(TypeC())
print(adapter.connect_usb()) # Type-C 连接
对象适配器
class Adapter:
def __init__(self, obj, adapted_methods):
self.obj = obj
self.__dict__.update(adapted_methods)
def typec_to_usb(self):
return self.obj.connect_typec()
adapter = Adapter(TypeC(), {"connect_usb": typec_to_usb})
print(adapter.connect_usb())
Python 特有:鸭子类型
# 只要方法签名一致,无需显式适配
def use_usb(device):
return device.connect_usb()
use_usb(Usb()) # USB 连接
use_usb(TypeCAdapter(TypeC())) # 适配后可用
适用场景
使用第三方库但接口不匹配
需要统一多个类的调用方式
无法修改现有类(无源码)Python 装饰器模式
Python 装饰器模式
装饰器模式动态地为对象添加职责,Python 的 @decorator 语法天然支持。
函数装饰器
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
print(f"{func.__name__} 耗时 {time.time()-start:.3f}s")
return result
return wrapper
@timer
def slow_work():
time.sleep(0.5)
slow_work() # slow_work 耗时 0.500s
类装饰器(装饰器模式)
class LoggingDecorator:
def __init__(self, component):
self.component = component
def operation(self):
print("操作前:记录日志")
result = self.component.operation()
print("操作后:记录日志")
return result
class BaseComponent:
def operation(self):
return "核心业务"
component = LoggingDecorator(BaseComponent())
print(component.operation())
# 操作前:记录日志
# 核心业务
# 操作后:记录日志
多层装饰
@timer
@cache
def compute(x):
return x ** 2
# 执行顺序: timer(cache(compute))
适用场景
日志、计时、缓存、鉴权
在不修改原函数/类的情况下增强功能
需要动态组合多种职责
注意
用 functools.wraps 保留函数元信息
装饰器按定义顺序从下往上包装Python 代理模式
Python 代理模式
代理模式为对象提供替身,控制对原对象的访问,常用于懒加载、访问控制、日志。
虚拟代理(懒加载)
class HeavyResource:
def __init__(self):
print("创建重型资源(耗时)")
self.data = "大量数据"
def read(self):
return self.data
class LazyProxy:
def __init__(self):
self._resource = None
def read(self):
if self._resource is None:
self._resource = HeavyResource() # 延迟创建
return self._resource.read()
proxy = LazyProxy()
print("代理已创建,尚未加载资源")
print(proxy.read()) # 此时才创建
保护代理(访问控制)
class BankAccount:
def withdraw(self, amount):
print(f"取款 {amount}")
class AccountProxy:
def __init__(self, account, user_role):
self.account = account
self.user_role = user_role
def withdraw(self, amount):
if self.user_role != "admin":
raise PermissionError("无权操作")
self.account.withdraw(amount)
与装饰器模式区别
代理: 控制访问(替身),接口与目标一致
装饰器: 增强功能,可叠加多种职责
Python 简化
# 懒加载可用 property + __getattr__
class Proxy:
def __getattr__(self, name):
# 首次访问时初始化
...Python 外观模式
Python 外观模式
外观模式为复杂子系统提供统一入口,简化调用。
实现
class CPU:
def start(self): return "CPU 启动"
def execute(self): return "CPU 执行"
class Memory:
def load(self): return "内存加载数据"
class HardDrive:
def read(self): return "硬盘读取"
class ComputerFacade:
"""外观:封装启动流程"""
def __init__(self):
self.cpu = CPU()
self.memory = Memory()
self.hard = HardDrive()
def start(self):
steps = [
self.cpu.start(),
self.memory.load(),
self.hard.read(),
self.cpu.execute(),
]
return " → ".join(steps)
# 客户端只面对一个简单接口
facade = ComputerFacade()
print(facade.start())
适用场景
子系统复杂,客户端只需要少量功能
希望为子系统提供简单默认入口
分层架构中为子系统提供门面
优点
客户端与子系统解耦
降低学习成本与出错概率
隐藏内部细节
注意
外观不应成为"万能类"——子系统仍可被直接使用
避免外观臃肿,保持单一职责Python 桥接模式
Python 桥接模式
桥接模式将抽象与实现分离,使两者可以独立变化,避免继承爆炸。
问题场景
形状 × 颜色: 圆形红色、圆形蓝色、方形红色...
如果用继承: 4 个类(2×2),扩展时组合爆炸
桥接实现
class Color:
def fill(self): raise NotImplementedError
class Red(Color):
def fill(self): return "红色"
class Blue(Color):
def fill(self): return "蓝色"
class Shape:
def __init__(self, color):
self.color = color # 持有实现引用
def draw(self): raise NotImplementedError
class Circle(Shape):
def draw(self):
return f"绘制圆形,填充{self.color.fill()}"
class Square(Shape):
def draw(self):
return f"绘制方形,填充{self.color.fill()}"
# 灵活组合:2 形状 × 2 颜色 = 4 种,只需 4 个类
red_circle = Circle(Red())
blue_square = Square(Blue())
print(red_circle.draw())
print(blue_square.draw())
适用场景
存在两个独立变化的维度
需要避免类爆炸
希望抽象与实现解耦
对比
适配器: 让已有接口协作
桥接: 设计阶段就分离抽象与实现Python 组合模式
Python 组合模式
组合模式将对象组织成树形结构,让客户端对单个对象和组合对象一视同仁。
实现
class Component:
def operation(self): raise NotImplementedError
class Leaf(Component):
"""叶子节点:文件"""
def __init__(self, name):
self.name = name
def operation(self):
return f"文件: {self.name}"
class Composite(Component):
"""组合节点:文件夹"""
def __init__(self, name):
self.name = name
self.children = []
def add(self, component):
self.children.append(component)
return self
def operation(self):
results = [child.operation() for child in self.children]
return f"目录: {self.name} [{' | '.join(results)}]"
# 构建树
root = Composite("根目录")
doc = Composite("文档")
root.add(doc)
doc.add(Leaf("报告.pdf"))
doc.add(Leaf("笔记.md"))
root.add(Leaf("readme.txt"))
print(root.operation())
# 目录: 根目录 [目录: 文档 [文件: 报告.pdf | 文件: 笔记.md] | 文件: readme.txt]
适用场景
树形结构(文件系统、组织架构、UI 组件树)
客户端无需区分叶子与组合
希望对整体和部分统一操作
优点与注意
优点: 简化客户端,易扩展新类型
注意: 组合与叶子的接口可能过度泛化
Python 中列表字典天然可作组合结构Python 享元模式
Python 享元模式
享元模式通过共享对象减少内存占用,适合大量相似对象的场景。
实现
class Character:
"""享元:共享的内部状态"""
def __init__(self, char, font):
self.char = char # 内部状态(共享)
self.font = font
def display(self, position):
# position 是外部状态(每次不同)
return f"'{self.char}'({self.font}) 位于{position}"
class CharacterFactory:
_pool = {}
@classmethod
def get(cls, char, font):
key = (char, font)
if key not in cls._pool:
cls._pool[key] = Character(char, font)
return cls._pool[key]
# 大量文本,字体有限的字符全部复用
f1 = CharacterFactory.get("A", "宋体")
f2 = CharacterFactory.get("A", "宋体")
f3 = CharacterFactory.get("A", "黑体")
print(f1 is f2) # True 共享!
print(f1 is f3) # False 字体不同
print(f1.display(1))
print(f1.display(2)) # 位置不同,显示不同
内部状态 vs 外部状态
内部状态: 共享不变(字符+字体)
外部状态: 随场景变化(位置),不存入享元
适用场景
大量相似对象(文本渲染、游戏粒子)
对象数量多导致内存压力大
对象可分为共享与独立部分Python 观察者模式
Python 观察者模式
观察者模式定义一对多依赖:主题状态变化时自动通知所有观察者。
实现
class Subject:
def __init__(self):
self._observers = []
self._state = None
def attach(self, observer):
self._observers.append(observer)
def detach(self, observer):
self._observers.remove(observer)
def notify(self):
for observer in self._observers:
observer.update(self._state)
def set_state(self, state):
self._state = state
self.notify()
class Observer:
def update(self, state): raise NotImplementedError
class EmailNotifier(Observer):
def update(self, state):
print(f"邮件通知: 状态变为 {state}")
class SMSNotifier(Observer):
def update(self, state):
print(f"短信通知: 状态变为 {state}")
# 使用
subject = Subject()
subject.attach(EmailNotifier())
subject.attach(SMSNotifier())
subject.set_state("已发货")
# 邮件通知: 状态变为 已发货
# 短信通知: 状态变为 已发货
函数式观察者(Python 风格)
class Subject:
def __init__(self):
self._handlers = []
def register(self, handler):
self._handlers.append(handler)
def notify(self, event):
for h in self._handlers:
h(event)
subject = Subject()
subject.register(lambda e: print(f"A 收到: {e}"))
subject.notify("事件!")
适用场景
事件驱动(UI 点击、消息推送)
发布-订阅模型
MVC 中 Model 通知 ViewPython 策略模式
Python 策略模式
策略模式定义一组算法,让它们可互换,客户端动态选择。
类实现
class Strategy:
def execute(self, data): raise NotImplementedError
class BubbleSort(Strategy):
def execute(self, data):
return sorted(data)
class QuickSort(Strategy):
def execute(self, data):
return sorted(data, reverse=True) # 演示不同策略
class Context:
def __init__(self, strategy):
self.strategy = strategy
def set_strategy(self, strategy):
self.strategy = strategy
def do_sort(self, data):
return self.strategy.execute(data)
context = Context(BubbleSort())
print(context.do_sort([3, 1, 2]))
context.set_strategy(QuickSort())
print(context.do_sort([3, 1, 2]))
Python 函数式策略(推荐)
def sort_asc(data): return sorted(data)
def sort_desc(data): return sorted(data, reverse=True)
def process(sort_func, data):
return sort_func(data)
process(sort_asc, [3, 1, 2]) # [1, 2, 3]
process(sort_desc, [3, 1, 2]) # [3, 2, 1]
适用场景
多个算法实现同一接口
需要运行时动态切换算法
避免大量 if-elif 分支
对比状态模式
策略: 客户端主动选择算法
状态: 状态自动驱动行为变化Python 命令模式
Python 命令模式
命令模式把请求封装为对象,支持参数化、队列、撤销操作。
实现
class Light:
def on(self): return "灯亮了"
def off(self): return "灯灭了"
class Command:
def execute(self): raise NotImplementedError
def undo(self): raise NotImplementedError
class LightOnCommand(Command):
def __init__(self, light):
self.light = light
def execute(self): return self.light.on()
def undo(self): return self.light.off()
class LightOffCommand(Command):
def __init__(self, light):
self.light = light
def execute(self): return self.light.off()
def undo(self): return self.light.on()
class RemoteControl:
def __init__(self):
self.history = []
def invoke(self, command):
result = command.execute()
self.history.append(command)
return result
def undo(self):
if self.history:
command = self.history.pop()
return command.undo()
return "无可撤销"
light = Light()
remote = RemoteControl()
print(remote.invoke(LightOnCommand(light))) # 灯亮了
print(remote.undo()) # 灯灭了
函数式命令(Python 风格)
def make_command(execute, undo=None):
return {"execute": execute, "undo": undo}
cmd = make_command(lambda: "执行", lambda: "撤销")
cmd["execute"]()
适用场景
撤销/重做功能
任务队列、宏命令
GUI 按钮与菜单操作Python 模板方法模式
Python 模板方法模式
模板方法在父类定义算法骨架,将可变步骤延迟到子类实现。
实现
from abc import ABC, abstractmethod
class DataMiner(ABC):
"""模板方法定义处理流程"""
def mine(self):
data = self.load_data()
processed = self.process(data)
self.output(processed)
def load_data(self):
return "原始数据"
@abstractmethod
def process(self, data):
pass
def output(self, data):
print(f"输出: {data}")
class CSVDataMiner(DataMiner):
def process(self, data):
return f"解析CSV: {data}"
class JSONDataMiner(DataMiner):
def process(self, data):
return f"解析JSON: {data}"
CSVDataMiner().mine() # 输出: 解析CSV: 原始数据
JSONDataMiner().mine() # 输出: 解析JSON: 原始数据
钩子方法
class DataMiner(ABC):
def mine(self):
data = self.load_data()
if self.need_process(): # 钩子
data = self.process(data)
self.output(data)
def need_process(self): # 默认钩子
return True
适用场景
多个流程结构相同、细节不同
框架设计(框架定骨架,用户实现钩子)
防止重复代码
对比策略模式
模板方法: 继承,骨架在父类
策略: 组合,算法可整体替换Python 迭代器模式
Python 迭代器模式
迭代器模式提供顺序访问集合元素的方式,Python 的迭代器协议天然内建。
Python 迭代器协议
iterable: 有 __iter__() 返回迭代器
iterator: 有 __next__() 返回下一个或抛 StopIteration
自定义迭代器
class CountDown:
def __init__(self, start):
self.start = start
def __iter__(self):
return self # 自身就是迭代器
def __next__(self):
if self.start <= 0:
raise StopIteration
self.start -= 1
return self.start + 1
for n in CountDown(3):
print(n) # 3 2 1
生成器(Python 风格迭代器)
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fibonacci(5):
print(num) # 0 1 1 2 3
itertools 常用工具
import itertools
itertools.chain([1,2], [3,4]) # 拼接迭代
itertools.islice(iter, 10) # 切片迭代
itertools.zip_longest(a, b) # 长zip
itertools.product([1,2], [3,4]) # 笛卡尔积
适用场景
需要统一遍历不同集合结构
大数据流式处理(惰性)
Python 中实现 __iter__/__next__ 或生成器即可Python 责任链模式
Python 责任链模式
责任链将请求沿处理器链传递,每个处理器决定处理还是转交下一个。
实现
class Handler:
def __init__(self):
self.next_handler = None
def set_next(self, handler):
self.next_handler = handler
return handler # 支持链式
def handle(self, request):
if self.next_handler:
return self.next_handler.handle(request)
return None
class Level1Support(Handler):
def handle(self, request):
if request <= 10:
return f"L1 处理: {request}"
return super().handle(request)
class Level2Support(Handler):
def handle(self, request):
if request <= 100:
return f"L2 处理: {request}"
return super().handle(request)
class Level3Support(Handler):
def handle(self, request):
return f"L3 处理: {request}"
# 构建链: L1 → L2 → L3
chain = Level1Support()
chain.set_next(Level2Support()).set_next(Level3Support())
print(chain.handle(5)) # L1 处理: 5
print(chain.handle(50)) # L2 处理: 50
print(chain.handle(500)) # L3 处理: 500
Python 简化(列表+循环)
handlers = [Level1Support(), Level2Support(), Level3Support()]
def handle(request):
for h in handlers:
result = h.handle(request)
if result:
return result
# 或优雅降级: try/except 链
适用场景
审批流、日志级别过滤
请求处理顺序不确定或动态调整
避免大量 if-elifPython 状态模式
Python 状态模式
状态模式让对象在内部状态变化时改变行为,消除大量条件判断。
实现
class State:
def handle(self, context): raise NotImplementedError
class DraftState(State):
def handle(self, context):
print("草稿状态: 审核中...")
context.state = ReviewState()
class ReviewState(State):
def handle(self, context):
print("审核状态: 已通过...")
context.state = PublishedState()
class PublishedState(State):
def handle(self, context):
print("已发布状态: 不可再变更")
class Document:
def __init__(self):
self.state = DraftState()
def next_step(self):
self.state.handle(self)
# 状态流转: 草稿 → 审核 → 发布
doc = Document()
doc.next_step() # 草稿状态: 审核中...
doc.next_step() # 审核状态: 已通过...
doc.next_step() # 已发布状态: 不可再变更
适用场景
对象行为随状态变化(订单、审批、播放器)
有大量 if-state 分支
状态转换规则复杂
对比策略模式
状态: 状态自动切换,行为随状态变化
策略: 客户端主动选择算法,状态不变Python 访问者模式
Python 访问者模式
访问者模式在不修改类的前提下,为对象结构增加新操作。
实现
class Node:
def accept(self, visitor):
raise NotImplementedError
class File(Node):
def __init__(self, name, size):
self.name = name
self.size = size
def accept(self, visitor):
return visitor.visit_file(self)
class Directory(Node):
def __init__(self, name):
self.name = name
self.children = []
def add(self, node):
self.children.append(node)
def accept(self, visitor):
return visitor.visit_directory(self)
class SizeVisitor:
"""统计总大小"""
def visit_file(self, file):
return file.size
def visit_directory(self, directory):
return sum(c.accept(self) for c in directory.children)
class CountVisitor:
"""统计文件数量"""
def visit_file(self, file):
return 1
def visit_directory(self, directory):
return sum(c.accept(self) for c in directory.children)
# 使用
root = Directory("root")
root.add(File("a.txt", 10))
sub = Directory("sub")
sub.add(File("b.log", 20))
root.add(sub)
print(SizeVisitor().visit_directory(root)) # 30
print(CountVisitor().visit_directory(root)) # 2
# 新增操作只需加新 Visitor,不用改 Node 类
适用场景
对象结构稳定但操作频繁变化
需要对结构执行多种不相关操作
避免在每个类加新方法
注意
增加新节点类型需要修改所有访问者(违反开闭原则)
Python 可用 singledispatch 简化Python 中介者模式
Python 中介者模式
中介者封装对象间的交互,减少对象之间的直接耦合。
实现
class ChatRoom:
"""中介者"""
def __init__(self):
self.users = []
def add_user(self, user):
self.users.append(user)
def send(self, message, sender):
for user in self.users:
if user != sender:
user.receive(message, sender.name)
class User:
def __init__(self, name, room):
self.name = name
self.room = room
room.add_user(self)
def send(self, message):
self.room.send(message, self)
def receive(self, message, sender):
print(f"{self.name} 收到来自 {sender} 的消息: {message}")
# 使用:用户之间不直接引用,只通过中介者
room = ChatRoom()
alice = User("Alice", room)
bob = User("Bob", room)
alice.send("大家好!") # Bob 收到
适用场景
对象之间交互复杂(UI 组件、聊天室、航班系统)
希望解耦网状依赖
交互逻辑集中管理
优缺点
优点: 减少耦合,交互集中
缺点: 中介者可能变得庞大(上帝对象)Python 备忘录模式
Python 备忘录模式
备忘录模式保存对象状态以便恢复,实现撤销功能。
实现
class Memento:
"""备忘录:不可变状态快照"""
def __init__(self, state):
self._state = state
def get_state(self):
return self._state
class Editor:
def __init__(self):
self.content = ""
def write(self, text):
self.content += text
def save(self):
return Memento(self.content)
def restore(self, memento):
self.content = memento.get_state()
class History:
def __init__(self):
self.snapshots = []
def push(self, memento):
self.snapshots.append(memento)
def pop(self):
return self.snapshots.pop()
# 使用
editor = Editor()
history = History()
editor.write("你好")
history.push(editor.save())
editor.write("世界")
history.push(editor.save())
editor.write("(误操作)")
print(editor.content) # 你好世界(误操作)
editor.restore(history.pop())
print(editor.content) # 你好世界
editor.restore(history.pop())
print(editor.content) # 你好
适用场景
撤销/重做(编辑器、游戏存档)
需要保存状态历史
状态快照需要与对象解耦
注意
快照量大时内存开销大
Python 可用 copy.deepcopy 简化Python 解释器模式
Python 解释器模式
解释器模式为语言定义文法,并解释执行句子,用于实现 DSL 和表达式求值。
实现(简单数学表达式)
class Expression:
def interpret(self): raise NotImplementedError
class Number(Expression):
def __init__(self, value):
self.value = value
def interpret(self):
return self.value
class Add(Expression):
def __init__(self, left, right):
self.left = left
self.right = right
def interpret(self):
return self.left.interpret() + self.right.interpret()
class Subtract(Expression):
def __init__(self, left, right):
self.left = left
self.right = right
def interpret(self):
return self.left.interpret() - self.right.interpret()
# 解析 (10 + 20) - 5 为语法树
expr = Subtract(Add(Number(10), Number(20)), Number(5))
print(expr.interpret()) # 25
Python 简化:直接求值/ast
# 用 Python 语法树模块解析
import ast
tree = ast.parse("10 + 20 - 5", mode="eval")
print(ast.literal_eval("10 + 20 - 5")) # 简单字面量
# eval 注意安全风险,生产勿用裸 eval
适用场景
实现 DSL(规则引擎、查询语言)
表达式求值(计算器、公式)
语法分析器
注意
语法复杂时解释器类爆炸,考虑用现成解析库
Python 有 pyparsing、PLY、lark 等解析工具