本文是设计模式的"百科全书",建议配合实践逐步消化。每种模式包含:意图、结构、Python实现、应用场景、优缺点对比。
第一部分:创建型模式(Creational Patterns)
创建型模式关注对象的实例化机制,将对象的创建与使用分离。
1. 单例模式(Singleton)
意图:确保一个类只有一个实例,并提供一个全局访问点。
结构:
┌─────────────┐
│ Singleton │◄────────┐
├─────────────┤ │
│ -instance │─────────┘
├─────────────┤
│ +getInstance()│
└─────────────┘
Python实现(5种方式):
python
import threading
from functools import wraps
# 方式1:线程安全单例(推荐)
class SingletonMeta(type):
_instances = {}
_lock = threading.Lock()
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
with cls._lock:
if cls not in cls._instances:
instance = super().__call__(*args, **kwargs)
cls._instances[cls] = instance
return cls._instances[cls]
class DatabasePool(metaclass=SingletonMeta):
def __init__(self):
self.connections = []
print("初始化数据库连接池")
# 方式2:装饰器实现
def singleton(cls):
instances = {}
lock = threading.Lock()
@wraps(cls)
def wrapper(*args, **kwargs):
if cls not in instances:
with lock:
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
@singleton
class Logger:
def __init__(self):
self.log_file = "app.log"
# 方式3:__new__实现(非线程安全,需加锁)
class FileManager:
_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
# 验证
pool1 = DatabasePool()
pool2 = DatabasePool()
print(pool1 is pool2) # True
应用场景:配置中心、连接池、线程池、缓存管理器
优缺点:
- ✅ 全局唯一访问点,节省资源
- ❌ 违反单一职责原则,隐藏依赖关系,测试困难
2. 工厂方法模式(Factory Method)
意图:定义创建对象的接口,让子类决定实例化哪个类。
结构:
┌──────────────┐ ┌──────────────┐
│ Creator │◄────────│ConcreteCreator│
├──────────────┤ ├──────────────┤
│+factoryMethod│◄────────│+factoryMethod │
│ +operation │ └──────────────┘
└──────┬───────┘ │
│ creates │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Product │◄────────│ConcreteProduct│
└──────────────┘ └──────────────┘
Python实现:
python
from abc import ABC, abstractmethod
from enum import Enum
class Document(ABC):
@abstractmethod
def open(self): pass
@abstractmethod
def save(self): pass
class PDFDocument(Document):
def open(self): print("打开PDF文档")
def save(self): print("保存PDF文档")
class WordDocument(Document):
def open(self): print("打开Word文档")
def save(self): print("保存Word文档")
class ExcelDocument(Document):
def open(self): print("打开Excel文档")
def save(self): print("保存Excel文档")
# 创建者
class Application(ABC):
@abstractmethod
def create_document(self) -> Document: pass # 工厂方法
def new_document(self):
doc = self.create_document()
doc.open()
return doc
class PDFApplication(Application):
def create_document(self): return PDFDocument()
class WordApplication(Application):
def create_document(self): return WordDocument()
class ExcelApplication(Application):
def create_document(self): return ExcelDocument()
# 使用
app = PDFApplication()
doc = app.new_document() # 打开PDF文档
应用场景:文档编辑器、跨平台UI组件、支付网关
3. 抽象工厂模式(Abstract Factory)
意图:创建相关对象家族,无需明确具体类。
结构:
┌─────────────────┐
│ AbstractFactory│
├─────────────────┤
│+createProductA()│
│+createProductB()│
└────────┬────────┘
│
┌────┴────┐
▼ ▼
┌─────────┐ ┌─────────┐
│Factory1 │ │Factory2 │
└────┬────┘ └────┬────┘
│ creates │
▼ ▼
┌─────────┐ ┌─────────┐
│ProductA1│ │ProductA2│
│ProductB1│ │ProductB2│
└─────────┘ └─────────┘
Python实现:
python
from abc import ABC, abstractmethod
# 抽象产品族:UI组件
class Button(ABC):
@abstractmethod
def render(self): pass
class Checkbox(ABC):
@abstractmethod
def check(self): pass
class TextField(ABC):
@abstractmethod
def input(self, text): pass
# Windows风格产品族
class WinButton(Button):
def render(self): print("渲染Windows风格按钮 ▯")
class WinCheckbox(Checkbox):
def check(self): print("Windows复选框 [✓]")
class WinTextField(TextField):
def input(self, text): print(f"Windows输入框: {text}")
# Mac风格产品族
class MacButton(Button):
def render(self): print("渲染Mac风格按钮 ⬭")
class MacCheckbox(Checkbox):
def check(self): print("Mac复选框 ☑")
class MacTextField(TextField):
def input(self, text): print(f"Mac输入框: {text}")
# 抽象工厂
class GUIFactory(ABC):
@abstractmethod
def create_button(self) -> Button: pass
@abstractmethod
def create_checkbox(self) -> Checkbox: pass
@abstractmethod
def create_textfield(self) -> TextField: pass
# 具体工厂
class WinFactory(GUIFactory):
def create_button(self): return WinButton()
def create_checkbox(self): return WinCheckbox()
def create_textfield(self): return WinTextField()
class MacFactory(GUIFactory):
def create_button(self): return MacButton()
def create_checkbox(self): return MacCheckbox()
def create_textfield(self): return MacTextField()
# 客户端代码
class Application:
def __init__(self, factory: GUIFactory):
self.button = factory.create_button()
self.checkbox = factory.create_checkbox()
self.textfield = factory.create_textfield()
def run(self):
self.button.render()
self.checkbox.check()
self.textfield.input("Hello World")
# 根据配置动态选择工厂
import platform
factory = WinFactory() if platform.system() == "Windows" else MacFactory()
app = Application(factory)
app.run()
应用场景:跨平台UI框架、数据库访问层(切换MySQL/PostgreSQL)、主题系统
4. 建造者模式(Builder)
意图:分步骤构建复杂对象,允许使用相同的创建过程生成不同的表示。
结构:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Director│─────►│ Builder │◄─────│Concrete │
│ │ │(abstract)│ │Builder │
└─────────┘ └────┬────┘ └────┬────┘
│ │
▼ ▼
┌─────────┐ ┌─────────┐
│ buildPart│ │ buildPart│
└────┬────┘ └────┬────┘
│ │
└────────►┌─────────┐
│ Product │
└─────────┘
Python实现(经典版+Pythonic版):
python
from abc import ABC, abstractmethod
from typing import Optional
# 产品:电脑
class Computer:
def __init__(self):
self.cpu: Optional[str] = None
self.memory: Optional[str] = None
self.storage: Optional[str] = None
self.gpu: Optional[str] = None
self.cooling: Optional[str] = None
def __str__(self):
specs = [f"{k}={v}" for k, v in self.__dict__.items() if v]
return f"Computer({', '.join(specs)})"
# 抽象建造者
class ComputerBuilder(ABC):
def __init__(self):
self.computer = Computer()
@abstractmethod
def build_cpu(self): pass
@abstractmethod
def build_memory(self): pass
@abstractmethod
def build_storage(self): pass
def build_gpu(self): pass # 可选步骤
def build_cooling(self): pass # 可选步骤
def get_result(self) -> Computer:
return self.computer
# 游戏电脑建造者
class GamingComputerBuilder(ComputerBuilder):
def build_cpu(self):
self.computer.cpu = "Intel i9-13900K"
return self
def build_memory(self):
self.computer.memory = "64GB DDR5"
return self
def build_storage(self):
self.computer.storage = "2TB NVMe SSD"
return self
def build_gpu(self):
self.computer.gpu = "RTX 4090"
return self
def build_cooling(self):
self.computer.cooling = "360mm水冷"
return self
# 办公电脑建造者
class OfficeComputerBuilder(ComputerBuilder):
def build_cpu(self):
self.computer.cpu = "Intel i5-13400"
return self
def build_memory(self):
self.computer.memory = "16GB DDR4"
return self
def build_storage(self):
self.computer.storage = "512GB SSD"
return self
# 导演类(可选,用于固定构建流程)
class Director:
def __init__(self, builder: ComputerBuilder):
self.builder = builder
def construct(self):
# 固定构建步骤
(self.builder
.build_cpu()
.build_memory()
.build_storage()
.build_gpu()
.build_cooling())
return self.builder.get_result()
# Pythonic版:使用链式调用和默认参数
class FluentComputerBuilder:
def __init__(self):
self.computer = Computer()
def set_cpu(self, cpu: str):
self.computer.cpu = cpu
return self
def set_memory(self, memory: str):
self.computer.memory = memory
return self
def set_storage(self, storage: str):
self.computer.storage = storage
return self
def set_gpu(self, gpu: str):
self.computer.gpu = gpu
return self
def build(self):
return self.computer
# 使用示例
print("=== 导演模式 ===")
gaming_builder = GamingComputerBuilder()
director = Director(gaming_builder)
gaming_pc = director.construct()
print(gaming_pc)
print("\n=== 流畅接口模式 ===")
office_pc = (FluentComputerBuilder()
.set_cpu("AMD Ryzen 5")
.set_memory("32GB")
.set_storage("1TB SSD")
.build())
print(office_pc)
应用场景:SQL构建器、测试数据构造器、复杂配置对象
5. 原型模式(Prototype)
意图:通过复制现有对象创建新对象,避免重复的初始化代码。
结构:
┌─────────────┐ clone() ┌─────────────┐
│ Prototype │───────────────────►│ Copy │
│ (abstract) │ │ │
└──────┬──────┘ └─────────────┘
│
▼
┌─────────────┐
│ConcretePrototype│
│ +clone() │
└─────────────┘
Python实现 (利用Python的copy模块):
python
import copy
from abc import ABC, abstractmethod
from typing import Any, Dict
class Prototype(ABC):
@abstractmethod
def clone(self) -> 'Prototype': pass
def deep_clone(self) -> 'Prototype':
return copy.deepcopy(self)
class Document(Prototype):
def __init__(self, title: str, content: str, author: str, metadata: Dict = None):
self.title = title
self.content = content
self.author = author
self.metadata = metadata or {}
self._history = [] # 内部状态
def clone(self) -> 'Document':
# 浅拷贝:共享metadata引用
new_doc = copy.copy(self)
new_doc._history = [] # 重置历史
return new_doc
def deep_clone(self) -> 'Document':
# 深拷贝:完全独立
new_doc = copy.deepcopy(self)
new_doc._history = []
return new_doc
def edit(self, new_content: str):
self._history.append(self.content)
self.content = new_content
def __str__(self):
return f"Document(title='{self.title}', author='{self.author}', content='{self.content[:20]}...')"
# 原型管理器(注册表模式)
class PrototypeRegistry:
def __init__(self):
self._prototypes: Dict[str, Prototype] = {}
def register(self, name: str, prototype: Prototype):
self._prototypes[name] = prototype
def create(self, name: str, **overrides) -> Prototype:
if name not in self._prototypes:
raise ValueError(f"Unknown prototype: {name}")
prototype = self._prototypes[name].deep_clone()
# 应用覆盖
for key, value in overrides.items():
setattr(prototype, key, value)
return prototype
# 使用
# 创建模板文档
template = Document("模板", "这是一份合同模板...", "法务部",
{"category": "合同", "confidential": True})
# 注册到原型管理器
registry = PrototypeRegistry()
registry.register("contract_template", template)
# 基于模板创建新文档
doc1 = registry.create("contract_template",
title="销售合同-2024-001",
author="销售部")
doc1.edit("甲方:ABC公司...")
doc2 = registry.create("contract_template",
title="采购合同-2024-002",
author="采购部")
print(doc1)
print(doc2)
print(f"模板未被修改: {template.content[:30]}...")
应用场景:对象创建成本高、需要保留历史状态、游戏角色模板
第二部分:结构型模式(Structural Patterns)
结构型模式关注如何组合类和对象形成更大的结构。
6. 适配器模式(Adapter)
意图:将不兼容的接口转换为可兼容的接口。
结构:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Client │───────►│ Target │◄───────│ Adapter │
│ │ │(interface)│ │ │
└─────────┘ └─────────┘ └───┬─────┘
│
│ adapts
▼
┌─────────┐
│ Adaptee│
│(existing)│
└─────────┘
Python实现(对象适配器+类适配器):
python
from abc import ABC, abstractmethod
# 目标接口(客户端期望的接口)
class MediaPlayer(ABC):
@abstractmethod
def play(self, filename: str): pass
# 被适配者(已有但接口不兼容的类)
class AdvancedMediaPlayer:
def play_mp4(self, filename: str):
print(f"播放MP4: {filename}")
def play_vlc(self, filename: str):
print(f"播放VLC: {filename}")
# 对象适配器(推荐,更灵活)
class MediaAdapter(MediaPlayer):
def __init__(self):
self.advanced_player = AdvancedMediaPlayer()
def play(self, filename: str):
if filename.endswith(".mp4"):
self.advanced_player.play_mp4(filename)
elif filename.endswith(".vlc"):
self.advanced_player.play_vlc(filename)
else:
print(f"不支持的格式: {filename}")
# 类适配器(使用多重继承,Python中较少用)
class ClassAdapter(MediaPlayer, AdvancedMediaPlayer):
def play(self, filename: str):
if filename.endswith(".mp4"):
self.play_mp4(filename)
elif filename.endswith(".vlc"):
self.play_vlc(filename)
# 客户端
class AudioPlayer(MediaPlayer):
def __init__(self):
self.adapter = MediaAdapter()
def play(self, filename: str):
if filename.endswith(".mp3"):
print(f"直接播放MP3: {filename}")
else:
# 使用适配器播放其他格式
self.adapter.play(filename)
# 使用
player = AudioPlayer()
player.play("song.mp3") # 直接播放MP3
player.play("movie.mp4") # 通过适配器播放MP4
player.play("video.vlc") # 通过适配器播放VLC
应用场景:第三方库集成、API版本兼容、遗留系统改造
7. 桥接模式(Bridge)
意图:将抽象与实现分离,使它们可以独立变化。
结构:
Abstraction ────────► Implementation
( refined ) ( concrete )
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Shape │◄───────────│ DrawingAPI │
│ │ bridge │ (interface) │
│ -drawing_api│ └──────┬──────┘
│ +draw() │ │
└──────┬──────┘ ┌───────┴───────┐
│ ▼ ▼
┌──────┴──────┐ ┌─────────┐ ┌─────────┐
│Circle,Rect │ │DrawAPI1 │ │DrawAPI2 │
└─────────────┘ └─────────┘ └─────────┘
Python实现:
python
from abc import ABC, abstractmethod
# 实现化角色:绘制API
class DrawingAPI(ABC):
@abstractmethod
def draw_circle(self, x: float, y: float, radius: float): pass
@abstractmethod
def draw_rectangle(self, x: float, y: float, width: float, height: float): pass
# 具体实现化:OpenGL绘制
class OpenGLAPI(DrawingAPI):
def draw_circle(self, x, y, radius):
print(f"[OpenGL] 绘制圆形: 中心({x},{y}), 半径{radius}")
def draw_rectangle(self, x, y, width, height):
print(f"[OpenGL] 绘制矩形: 位置({x},{y}), 尺寸{width}x{height}")
# 具体实现化:DirectX绘制
class DirectXAPI(DrawingAPI):
def draw_circle(self, x, y, radius):
print(f"[DirectX] 绘制圆形: 中心({x},{y}), 半径{radius}")
def draw_rectangle(self, x, y, width, height):
print(f"[DirectX] 绘制矩形: 位置({x},{y}), 尺寸{width}x{height}")
# 抽象化角色:形状
class Shape(ABC):
def __init__(self, drawing_api: DrawingAPI):
self.drawing_api = drawing_api # 桥接点
@abstractmethod
def draw(self): pass
@abstractmethod
def resize(self, factor: float): pass
# 扩充抽象化:圆形
class CircleShape(Shape):
def __init__(self, x, y, radius, drawing_api: DrawingAPI):
super().__init__(drawing_api)
self.x = x
self.y = y
self.radius = radius
def draw(self):
self.drawing_api.draw_circle(self.x, self.y, self.radius)
def resize(self, factor):
self.radius *= factor
# 扩充抽象化:矩形
class RectangleShape(Shape):
def __init__(self, x, y, width, height, drawing_api: DrawingAPI):
super().__init__(drawing_api)
self.x = x
self.y = y
self.width = width
self.height = height
def draw(self):
self.drawing_api.draw_rectangle(self.x, self.y, self.width, self.height)
def resize(self, factor):
self.width *= factor
self.height *= factor
# 使用:抽象和实现独立变化
shapes = [
CircleShape(1, 2, 3, OpenGLAPI()),
CircleShape(5, 7, 11, DirectXAPI()),
RectangleShape(0, 0, 100, 50, OpenGLAPI())
]
for shape in shapes:
shape.draw()
shape.resize(2)
shape.draw()
print("---")
应用场景:跨平台图形渲染、多种数据库驱动、消息发送(邮件/短信/推送)
8. 组合模式(Composite)
意图:将对象组合成树形结构,以表示"部分-整体"的层次结构,使客户端对单个对象和组合对象的使用具有一致性。
结构:
Component
(interface)
│
┌───────────┴───────────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ Leaf │ │ Composite│
│(单个对象)│ │(组合对象) │
└─────────┘ └────┬────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
Component Component Component
(Leaf/Composite)
Python实现:
python
from abc import ABC, abstractmethod
from typing import List
# 组件接口
class FileSystemComponent(ABC):
def __init__(self, name: str):
self.name = name
@abstractmethod
def get_size(self) -> int: pass
@abstractmethod
def display(self, indent: int = 0): pass
def add(self, component):
raise NotImplementedError("叶子节点不能添加子节点")
def remove(self, component):
raise NotImplementedError("叶子节点不能移除子节点")
# 叶子节点:文件
class File(FileSystemComponent):
def __init__(self, name: str, size: int):
super().__init__(name)
self._size = size
def get_size(self) -> int:
return self._size
def display(self, indent: int = 0):
print(" " * indent + f"📄 {self.name} ({self._size} bytes)")
# 组合节点:文件夹
class Folder(FileSystemComponent):
def __init__(self, name: str):
super().__init__(name)
self._children: List[FileSystemComponent] = []
def add(self, component: FileSystemComponent):
self._children.append(component)
return self # 支持链式调用
def remove(self, component: FileSystemComponent):
self._children.remove(component)
def get_size(self) -> int:
return sum(child.get_size() for child in self._children)
def display(self, indent: int = 0):
print(" " * indent + f"📁 {self.name}/")
for child in self._children:
child.display(indent + 1)
# 构建文件系统树
root = Folder("root")
documents = Folder("documents")
pictures = Folder("pictures")
documents.add(File("resume.pdf", 1024))
documents.add(File("cover_letter.docx", 512))
pictures.add(File("photo1.jpg", 2048))
pictures.add(File("photo2.jpg", 3072))
root.add(documents)
root.add(pictures)
root.add(File("readme.txt", 256))
# 统一操作
root.display()
print(f"\n总大小: {root.get_size()} bytes")
应用场景:UI组件树、组织架构、文件系统、菜单系统
9. 装饰器模式(Decorator)
意图:动态地给对象添加额外职责,比子类更灵活。
结构:
┌─────────┐ ┌─────────────┐ ┌─────────────┐
│ Component│◄─────│ Decorator │◄─────│ConcreteDecorator│
│(interface)│ │ -component │ │ +addedBehavior │
└────┬────┘ └─────────────┘ └─────────────┘
▲ │
│ │
ConcreteComponent◄─────────────────────────┘
Python实现(含Python特有的函数装饰器对比):
python
from abc import ABC, abstractmethod
# 组件接口
class Coffee(ABC):
@abstractmethod
def cost(self) -> float: pass
@abstractmethod
def description(self) -> str: pass
# 具体组件
class SimpleCoffee(Coffee):
def cost(self) -> float:
return 10.0
def description(self) -> str:
return "简单咖啡"
# 装饰器基类
class CoffeeDecorator(Coffee, ABC):
def __init__(self, coffee: Coffee):
self._coffee = coffee
def cost(self) -> float:
return self._coffee.cost()
def description(self) -> str:
return self._coffee.description()
# 具体装饰器
class Milk(CoffeeDecorator):
def cost(self) -> float:
return self._coffee.cost() + 2.0
def description(self) -> str:
return self._coffee.description() + ", 牛奶"
class Sugar(CoffeeDecorator):
def cost(self) -> float:
return self._coffee.cost() + 0.5
def description(self) -> str:
return self._coffee.description() + ", 糖"
class Whip(CoffeeDecorator):
def cost(self) -> float:
return self._coffee.cost() + 3.0
def description(self) -> str:
return self._coffee.description() + ", 奶泡"
class Vanilla(CoffeeDecorator):
def cost(self) -> float:
return self._coffee.cost() + 1.5
def description(self) -> str:
return self._coffee.description() + ", 香草糖浆"
# 使用:层层包裹,无限组合
coffee = SimpleCoffee()
coffee = Milk(coffee)
coffee = Sugar(coffee)
coffee = Sugar(coffee) # 双份糖
coffee = Whip(coffee)
print(f"{coffee.description()} = ¥{coffee.cost()}")
# 简单咖啡, 牛奶, 糖, 糖, 奶泡 = ¥16.0
# Python函数装饰器对比(语法糖)
def discount_decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result * 0.9 # 9折优惠
return wrapper
class CoffeeShop:
@discount_decorator
def get_price(self):
return 100
# 注意:函数装饰器是语法糖,对象装饰器是结构模式
应用场景:I/O流包装(Java)、权限检查、缓存、日志记录
10. 外观模式(Facade)
意图:为子系统中的一组接口提供一个统一的高层接口,使子系统更容易使用。
结构:
┌─────────┐ ┌─────────────────────────────┐
│ Client │─────►│ Facade │
│ │ │ ┌─────┐ ┌─────┐ ┌─────┐ │
└─────────┘ │ │SubA │ │SubB │ │SubC │ │
│ └─────┘ └─────┘ └─────┘ │
│ (隐藏复杂子系统) │
└─────────────────────────────┘
Python实现:
python
# 复杂子系统:多个类
class CPU:
def freeze(self): print("CPU: 冻结处理器")
def jump(self, position): print(f"CPU: 跳转到地址 {position}")
def execute(self): print("CPU: 执行指令")
class Memory:
def load(self, position, data):
print(f"Memory: 从位置 {position} 加载数据 '{data}'")
class HardDrive:
def read(self, lba, size):
return f"硬盘数据 [LBA:{lba}, Size:{size}]"
class PowerSupply:
def turn_on(self): print("电源: 开启")
def check_voltage(self): print("电源: 电压检查通过")
class FanController:
def set_speed(self, rpm): print(f"风扇: 设置为 {rpm} RPM")
# 外观:电脑启动器
class ComputerFacade:
def __init__(self):
self.cpu = CPU()
self.memory = Memory()
self.hard_drive = HardDrive()
self.power = PowerSupply()
self.fan = FanController()
def start(self):
"""一键启动电脑(隐藏复杂流程)"""
print("=== 启动电脑 ===")
self.power.turn_on()
self.power.check_voltage()
self.fan.set_speed(3000)
self.cpu.freeze()
boot_data = self.hard_drive.read(0, 1024)
self.memory.load(0, boot_data)
self.cpu.jump(0)
self.cpu.execute()
self.fan.set_speed(1500) # 启动后降速
print("=== 启动完成 ===\n")
def shutdown(self):
"""一键关机"""
print("=== 关闭电脑 ===")
self.fan.set_speed(0)
self.cpu.freeze()
self.power.turn_on() # 实际应该是turn_off
print("=== 关闭完成 ===")
# 客户端使用
computer = ComputerFacade()
computer.start()
computer.shutdown()
# 对比:不使用外观的复杂调用
# cpu = CPU()
# memory = Memory()
# hard_drive = HardDrive()
# ... 需要手动协调所有组件
应用场景:API网关、ORM框架、复杂库的简单封装、微服务聚合层
11. 享元模式(Flyweight)
意图:运用共享技术有效地支持大量细粒度的对象。
结构:
┌─────────┐ ┌─────────────────┐
│ Client │─────►│ FlyweightFactory│
│ │ │ -flyweights │
└─────────┘ │ +getFlyweight()│
└────────┬────────┘
│
┌────────┴────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Flyweight │ │UnsharedConcrete│
│(intrinsic) │ │Flyweight │
│ +operation │ │(extrinsic) │
└─────────────┘ └─────────────┘
Python实现(含对象池优化):
python
from typing import Dict, Tuple
# 享元接口
class CharacterStyle:
"""共享的内部状态:字体样式"""
_pool: Dict[Tuple, 'CharacterStyle'] = {}
def __new__(cls, font: str, size: int, color: str):
# 单例池:相同参数返回同一对象
key = (font, size, color)
if key not in cls._pool:
instance = super().__new__(cls)
cls._pool[key] = instance
instance._initialized = False
return cls._pool[key]
def __init__(self, font: str, size: int, color: str):
# 防止重复初始化
if self._initialized:
return
self.font = font
self.size = size
self.color = color
print(f"创建新样式: {font}/{size}pt/{color}")
self._initialized = True
def render(self, character: str, x: int, y: int):
"""外部状态作为参数传入"""
print(f"渲染 '{character}' 在({x},{y}) 使用 {self.font}/{self.size}pt/{self.color}")
class Character:
"""包含享元引用的字符"""
def __init__(self, char: str, style: CharacterStyle, x: int, y: int):
self.char = char # 外部状态
self.style = style # 内部状态(共享)
self.x = x
self.y = y
def display(self):
self.style.render(self.char, self.x, self.y)
# 文档编辑器模拟
class Document:
def __init__(self):
self.characters: list[Character] = []
def add_text(self, text: str, font: str, size: int, color: str, start_x: int, y: int):
x = start_x
for char in text:
style = CharacterStyle(font, size, color) # 自动复用
self.characters.append(Character(char, style, x, y))
x += size # 简单布局
def render(self):
for char in self.characters:
char.display()
# 使用:大量字符共享少量样式
doc = Document()
doc.add_text("Hello", "Arial", 12, "black", 0, 0)
doc.add_text("World", "Arial", 12, "black", 60, 0)
doc.add_text("Python", "Arial", 12, "black", 120, 0)
doc.add_text("Design", "Times", 14, "red", 0, 20)
doc.add_text("Patterns", "Times", 14, "red", 60, 20)
print(f"\n样式池大小: {len(CharacterStyle._pool)}") # 只有2个样式对象
doc.render()
应用场景:文本编辑器字符样式、游戏粒子系统、棋盘游戏棋子、数据库连接池
12. 代理模式(Proxy)
意图:为其他对象提供一种代理以控制对这个对象的访问。
结构:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Client │─────►│ Proxy │─────►│RealSubject│
│ │ │-realSubject │ │
└─────────┘ │+request()│ │+request()│
│(control)│ │ (actual) │
└─────────┘ └─────────┘
Python实现(4种代理类型):
python
from abc import ABC, abstractmethod
import time
from functools import lru_cache
# 主题接口
class Image(ABC):
@abstractmethod
def display(self): pass
@abstractmethod
def get_filename(self) -> str: pass
# 真实主题
class RealImage(Image):
def __init__(self, filename: str):
self._filename = filename
self._load_from_disk()
def _load_from_disk(self):
print(f" [IO] 从磁盘加载大图: {self._filename} (耗时2秒)")
time.sleep(2)
def display(self):
print(f" 显示图片: {self._filename}")
def get_filename(self):
return self._filename
# 1. 虚拟代理:延迟加载
class VirtualProxy(Image):
def __init__(self, filename: str):
self._filename = filename
self._real_image = None # 延迟初始化
def display(self):
if self._real_image is None:
print(f" [虚拟代理] 首次访问,创建真实对象")
self._real_image = RealImage(self._filename)
else:
print(f" [虚拟代理] 使用缓存的对象")
self._real_image.display()
def get_filename(self):
return self._filename
# 2. 保护代理:访问控制
class ProtectedProxy(Image):
def __init__(self, real_image: RealImage, user_role: str):
self._real_image = real_image
self._user_role = user_role
def display(self):
if self._user_role == "admin":
self._real_image.display()
else:
print(f" [保护代理] 拒绝访问: 需要admin权限")
def get_filename(self):
return self._real_image.get_filename()
# 3. 智能引用:引用计数、日志等
class SmartProxy(Image):
def __init__(self, filename: str):
self._real_image = RealImage(filename)
self._access_count = 0
def display(self):
self._access_count += 1
print(f" [智能引用] 第{self._access_count}次访问")
self._real_image.display()
def get_filename(self):
return self._real_image.get_filename()
# 4. 远程代理(示意,实际需RPC框架)
class RemoteProxy(Image):
def __init__(self, filename: str, server_url: str):
self._filename = filename
self._server_url = server_url
def display(self):
print(f" [远程代理] 向{self._server_url}请求图片")
# 实际这里会进行网络请求
print(f" 远程显示: {self._filename}")
def get_filename(self):
return self._filename
# 使用演示
print("=== 虚拟代理:延迟加载 ===")
thumb1 = VirtualProxy("photo1.jpg")
thumb2 = VirtualProxy("photo2.jpg")
print("图片列表创建完成(无实际加载)")
print("\n用户点击 photo1:")
thumb1.display() # 首次加载
print("\n用户再次点击 photo1:")
thumb1.display() # 使用缓存
print("\n=== 保护代理:权限控制 ===")
confidential = RealImage("secret.png")
protected = ProtectedProxy(confidential, "guest")
protected.display() # 拒绝访问
admin_proxy = ProtectedProxy(confidential, "admin")
admin_proxy.display() # 允许访问
应用场景:图片懒加载、权限控制、RPC远程调用、ORM延迟加载
第三部分:行为型模式(Behavioral Patterns)
行为型模式关注对象之间的通信和责任分配。
13. 责任链模式(Chain of Responsibility)
意图:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
结构:
Client ──► Handler ◄──────┐
(abstract) │
+handleRequest()│
+setSuccessor() │
▲ │
│ │
┌────────┴────────┐
▼ ▼
ConcreteHandler1 ConcreteHandler2
(can handle?) (can handle?)
Python实现:
python
from abc import ABC, abstractmethod
from typing import Optional
from enum import Enum
class RequestType(Enum):
TECHNICAL = "技术问题"
BILLING = "账单问题"
SALES = "销售咨询"
GENERAL = "一般咨询"
class SupportRequest:
def __init__(self, type: RequestType, description: str, priority: int):
self.type = type
self.description = description
self.priority = priority # 1-5,5最高
# 处理者接口
class SupportHandler(ABC):
def __init__(self):
self._next: Optional[SupportHandler] = None
def set_next(self, handler: 'SupportHandler'):
self._next = handler
return handler # 支持链式设置
def handle(self, request: SupportRequest):
if self.can_handle(request):
self.process(request)
elif self._next:
print(f" [{self.__class__.__name__}] 无法处理,转交下一级")
self._next.handle(request)
else:
print(f" [系统] 无人可以处理该请求: {request.description}")
@abstractmethod
def can_handle(self, request: SupportRequest) -> bool: pass
@abstractmethod
def process(self, request: SupportRequest): pass
# 具体处理者:一线客服
class JuniorSupport(SupportHandler):
def can_handle(self, request: SupportRequest) -> bool:
return request.type == RequestType.GENERAL and request.priority <= 2
def process(self, request: SupportRequest):
print(f" [一线客服] 处理一般咨询: {request.description}")
# 具体处理者:技术专员
class TechnicalSupport(SupportHandler):
def can_handle(self, request: SupportRequest) -> bool:
return request.type == RequestType.TECHNICAL and request.priority <= 3
def process(self, request: SupportRequest):
print(f" [技术专员] 处理技术问题: {request.description}")
# 具体处理者:主管
class Supervisor(SupportHandler):
def can_handle(self, request: SupportRequest) -> bool:
return request.priority <= 4
def process(self, request: SupportRequest):
print(f" [主管] 处理高优先级问题: {request.description}")
# 具体处理者:经理(最终处理者)
class Manager(SupportHandler):
def can_handle(self, request: SupportRequest) -> bool:
return True # 可以处理任何请求
def process(self, request: SupportRequest):
print(f" [经理] 最终处理: {request.description}")
# 构建责任链
chain = JuniorSupport()
chain.set_next(TechnicalSupport()).set_next(Supervisor()).set_next(Manager())
# 测试不同请求
requests = [
SupportRequest(RequestType.GENERAL, "如何重置密码?", 1),
SupportRequest(RequestType.TECHNICAL, "服务器500错误", 2),
SupportRequest(RequestType.TECHNICAL, "数据库崩溃", 5), # 超出一线和专员能力
SupportRequest(RequestType.BILLING, "申请退款", 4),
]
for req in requests:
print(f"\n新请求: {req.type.value} (优先级{req.priority})")
chain.handle(req)
应用场景:审批流程、异常处理链、中间件管道(Django/Express)、日志记录级别
14. 命令模式(Command)
意图:将请求封装为对象,以便使用不同的请求、队列或日志来参数化其他对象,同时支持可撤销操作。
结构:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Client │─────►│ Command │◄─────│ Receiver │
│ │ │(abstract)│ │(knows how)│
└─────────┘ │+execute()│ └─────────┘
└────┬────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
ConcreteCommand ConcreteCommand ...
(LightOn) (FanOff)
Python实现(含撤销/重做):
python
from abc import ABC, abstractmethod
from typing import List, Optional
from enum import Enum
class Light:
"""接收者:电灯"""
def __init__(self, location: str):
self.location = location
self.is_on = False
def on(self):
self.is_on = True
print(f"[{self.location}] 灯已打开 💡")
def off(self):
self.is_on = False
print(f"[{self.location}] 灯已关闭 🌑")
class Fan:
"""接收者:风扇"""
def __init__(self, location: str):
self.location = location
self.speed = 0
def high(self):
self.speed = 3
print(f"[{self.location}] 风扇高速运转 ༄")
def medium(self):
self.speed = 2
print(f"[{self.location}] 风扇中速运转 ~")
def low(self):
self.speed = 1
print(f"[{self.location}] 风扇低速运转 ﹋")
def off(self):
self.speed = 0
print(f"[{self.location}] 风扇停止 ✋")
# 命令接口
class Command(ABC):
@abstractmethod
def execute(self): pass
@abstractmethod
def undo(self): pass
def get_name(self) -> str:
return self.__class__.__name__
# 具体命令
class LightOnCommand(Command):
def __init__(self, light: Light):
self.light = light
self.prev_state = False
def execute(self):
self.prev_state = self.light.is_on
self.light.on()
def undo(self):
if not self.prev_state:
self.light.off()
class LightOffCommand(Command):
def __init__(self, light: Light):
self.light = light
self.prev_state = False
def execute(self):
self.prev_state = self.light.is_on
self.light.off()
def undo(self):
if self.prev_state:
self.light.on()
class FanHighCommand(Command):
def __init__(self, fan: Fan):
self.fan = fan
self.prev_speed = 0
def execute(self):
self.prev_speed = self.fan.speed
self.fan.high()
def undo(self):
if self.prev_speed == 0:
self.fan.off()
elif self.prev_speed == 1:
self.fan.low()
elif self.prev_speed == 2:
self.fan.medium()
else:
self.fan.high()
# 宏命令(组合命令)
class MacroCommand(Command):
def __init__(self, commands: List[Command]):
self.commands = commands
def execute(self):
for cmd in self.commands:
cmd.execute()
def undo(self):
for cmd in reversed(self.commands):
cmd.undo()
# 调用者:遥控器
class RemoteControl:
def __init__(self):
self._commands: List[Optional[Command]] = [None] * 7 # 7个插槽
self._undo_stack: List[Command] = []
self._redo_stack: List[Command] = []
def set_command(self, slot: int, command: Command):
self._commands[slot] = command
def press_button(self, slot: int):
if self._commands[slot]:
cmd = self._commands[slot]
cmd.execute()
self._undo_stack.append(cmd)
self._redo_stack.clear() # 新操作清空重做栈
else:
print(f"插槽{slot}未设置命令")
def press_undo(self):
if self._undo_stack:
cmd = self._undo_stack.pop()
cmd.undo()
self._redo_stack.append(cmd)
print(f"[撤销] {cmd.get_name()}")
else:
print("无操作可撤销")
def press_redo(self):
if self._redo_stack:
cmd = self._redo_stack.pop()
cmd.execute()
self._undo_stack.append(cmd)
print(f"[重做] {cmd.get_name()}")
else:
print("无操作可重做")
# 使用
living_room_light = Light("客厅")
bedroom_fan = Fan("卧室")
remote = RemoteControl()
remote.set_command(0, LightOnCommand(living_room_light))
remote.set_command(1, LightOffCommand(living_room_light))
remote.set_command(2, FanHighCommand(bedroom_fan))
# 宏命令:"回家模式" = 开灯 + 开风扇
home_mode = MacroCommand([
LightOnCommand(living_room_light),
FanHighCommand(bedroom_fan)
])
remote.set_command(3, home_mode)
print("=== 测试遥控器 ===")
remote.press_button(0) # 开灯
remote.press_button(2) # 风扇高速
remote.press_undo() # 撤销风扇
remote.press_undo() # 撤销开灯
remote.press_redo() # 重做开灯
remote.press_button(3) # 回家模式
remote.press_undo() # 撤销整个宏命令
应用场景:GUI菜单项、线程池任务、事务管理、游戏动作系统、智能家居
15. 解释器模式(Interpreter)
意图:给定一个语言,定义它的文法表示,并定义一个解释器来解释语言中的句子。
结构:
┌─────────┐ ┌─────────────────┐
│ Client │─────►│ Context │
│ │ │ (全局信息) │
└─────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Expression │
│ (interpret()) │
└────────┬────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
TerminalExpression NonTerminalExpression ...
(变量/数字) (操作符)
Python实现(简单的规则引擎):
python
from abc import ABC, abstractmethod
from typing import Dict, List
# 上下文:包含变量赋值
class Context:
def __init__(self):
self.variables: Dict[str, int] = {}
def set_variable(self, name: str, value: int):
self.variables[name] = value
def get_variable(self, name: str) -> int:
if name not in self.variables:
raise ValueError(f"未定义变量: {name}")
return self.variables[name]
# 抽象表达式
class Expression(ABC):
@abstractmethod
def interpret(self, context: Context) -> int: pass
@abstractmethod
def __str__(self) -> str: pass
# 终结符表达式:数字
class NumberExpression(Expression):
def __init__(self, value: int):
self.value = value
def interpret(self, context: Context) -> int:
return self.value
def __str__(self) -> str:
return str(self.value)
# 终结符表达式:变量
class VariableExpression(Expression):
def __init__(self, name: str):
self.name = name
def interpret(self, context: Context) -> int:
return context.get_variable(self.name)
def __str__(self) -> str:
return self.name
# 非终结符表达式:加法
class AddExpression(Expression):
def __init__(self, left: Expression, right: Expression):
self.left = left
self.right = right
def interpret(self, context: Context) -> int:
return self.left.interpret(context) + self.right.interpret(context)
def __str__(self) -> str:
return f"({self.left} + {self.right})"
# 非终结符表达式:减法
class SubtractExpression(Expression):
def __init__(self, left: Expression, right: Expression):
self.left = left
self.right = right
def interpret(self, context: Context) -> int:
return self.left.interpret(context) - self.right.interpret(context)
def __str__(self) -> str:
return f"({self.left} - {self.right})"
# 非终结符表达式:乘法
class MultiplyExpression(Expression):
def __init__(self, left: Expression, right: Expression):
self.left = left
self.right = right
def interpret(self, context: Context) -> int:
return self.left.interpret(context) * self.right.interpret(context)
def __str__(self) -> str:
return f"({self.left} * {self.right})"
# 解析器:将字符串转换为表达式树
class ExpressionParser:
def parse(self, expression: str) -> Expression:
"""
简单解析器,支持: 数字、变量、+ - *
示例: "a + b * 2"
"""
tokens = expression.replace("(", " ( ").replace(")", " ) ").split()
return self._parse_expression(tokens, 0)[0]
def _parse_expression(self, tokens: List[str], pos: int):
# 简化的递归下降解析
left, pos = self._parse_term(tokens, pos)
while pos < len(tokens) and tokens[pos] in ('+', '-'):
op = tokens[pos]
pos += 1
right, pos = self._parse_term(tokens, pos)
if op == '+':
left = AddExpression(left, right)
else:
left = SubtractExpression(left, right)
return left, pos
def _parse_term(self, tokens: List[str], pos: int):
left, pos = self._parse_factor(tokens, pos)
while pos < len(tokens) and tokens[pos] == '*':
pos += 1
right, pos = self._parse_factor(tokens, pos)
left = MultiplyExpression(left, right)
return left, pos
def _parse_factor(self, tokens: List[str], pos: int):
token = tokens[pos]
if token.isdigit():
return NumberExpression(int(token)), pos + 1
elif token.isalpha():
return VariableExpression(token), pos + 1
elif token == '(':
expr, pos = self._parse_expression(tokens, pos + 1)
if pos < len(tokens) and tokens[pos] == ')':
pos += 1
return expr, pos
else:
raise ValueError(f"未知token: {token}")
# 使用
context = Context()
context.set_variable("x", 10)
context.set_variable("y", 5)
# 手动构建表达式树
expr = AddExpression(
VariableExpression("x"),
MultiplyExpression(
NumberExpression(2),
VariableExpression("y")
)
)
print(f"表达式: {expr}")
print(f"结果: {expr.interpret(context)}") # 10 + 2*5 = 20
# 使用解析器
parser = ExpressionParser()
parsed = parser.parse("x + y * 3 - 2")
print(f"\n解析: {parsed}")
print(f"结果: {parsed.interpret(context)}") # 10 + 5*3 - 2 = 23
应用场景:正则表达式引擎、SQL解析器、规则引擎、配置文件解析
16. 迭代器模式(Iterator)
意图:提供一种方法顺序访问聚合对象中的各个元素,而又不暴露其内部表示。
结构:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Client │─────►│ Iterator│◄─────│Aggregate│
│ │ │+first() │ │+createIterator│
└─────────┘ │+next() │ └────┬────┘
│+isDone() │ │
│+current()│ ┌──────┴──────┐
└─────────┘ ▼ ▼
Concrete ConcreteIterator
Aggregate (has cursor)
Python实现(对比Python原生迭代器):
python
from abc import ABC, abstractmethod
from typing import Any, List
from collections.abc import Iterable, Iterator
# 传统迭代器模式实现
class Book:
def __init__(self, title: str, author: str):
self.title = title
self.author = author
def __str__(self):
return f"《{self.title}》 by {self.author}"
# 抽象迭代器
class BookIterator(ABC):
@abstractmethod
def has_next(self) -> bool: pass
@abstractmethod
def next(self) -> Book: pass
@abstractmethod
def reset(self): pass
# 具体迭代器:按顺序遍历
class SequentialIterator(BookIterator):
def __init__(self, books: List[Book]):
self._books = books
self._index = 0
def has_next(self) -> bool:
return self._index < len(self._books)
def next(self) -> Book:
if not self.has_next():
raise StopIteration()
book = self._books[self._index]
self._index += 1
return book
def reset(self):
self._index = 0
# 具体迭代器:按作者名过滤
class AuthorFilterIterator(BookIterator):
def __init__(self, books: List[Book], author: str):
self._books = books
self._author = author
self._index = 0
self._filter_and_sort()
def _filter_and_sort(self):
self._filtered = [b for b in self._books if b.author == self._author]
self._filtered.sort(key=lambda x: x.title)
self._index = 0
def has_next(self) -> bool:
return self._index < len(self._filtered)
def next(self) -> Book:
if not self.has_next():
raise StopIteration()
book = self._filtered[self._index]
self._index += 1
return book
def reset(self):
self._index = 0
# 聚合接口
class BookCollection(ABC):
@abstractmethod
def create_iterator(self) -> BookIterator: pass
@abstractmethod
def create_author_iterator(self, author: str) -> BookIterator: pass
# 具体聚合:图书馆
class Library(BookCollection):
def __init__(self):
self._books: List[Book] = []
def add_book(self, book: Book):
self._books.append(book)
def create_iterator(self) -> BookIterator:
return SequentialIterator(self._books)
def create_author_iterator(self, author: str) -> BookIterator:
return AuthorFilterIterator(self._books, author)
# Pythonic实现:使用生成器(更简洁)
class ModernLibrary:
def __init__(self):
self._books: List[Book] = []
def add_book(self, book: Book):
self._books.append(book)
def __iter__(self):
"""实现Iterable接口,支持for循环"""
return iter(self._books)
def by_author(self, author: str):
"""生成器实现过滤迭代"""
for book in self._books:
if book.author == author:
yield book
def reverse_iterator(self):
"""反向迭代器"""
for book in reversed(self._books):
yield book
# 使用对比
print("=== 传统迭代器模式 ===")
library = Library()
library.add_book(Book("设计模式", "GoF"))
library.add_book(Book("Python编程", "Guido"))
library.add_book(Book("Java核心技术", "GoF"))
iterator = library.create_iterator()
while iterator.has_next():
print(f" {iterator.next()}")
print("\n按作者'GoF'过滤:")
author_iter = library.create_author_iterator("GoF")
while author_iter.has_next():
print(f" {author_iter.next()}")
print("\n=== Pythonic实现 ===")
modern = ModernLibrary()
modern.add_book(Book("Clean Code", "Robert"))
modern.add_book(Book("Refactoring", "Martin"))
modern.add_book(Book("Clean Architecture", "Robert"))
print("所有书籍:")
for book in modern: # 直接使用for循环
print(f" {book}")
print("\nRobert的书籍:")
for book in modern.by_author("Robert"):
print(f" {book}")
print("\n反向遍历:")
for book in modern.reverse_iterator():
print(f" {book}")
应用场景:集合遍历、数据库游标、树形结构遍历、分页器
17. 中介者模式(Mediator)
意图:定义一个对象来封装一组对象的交互,减少对象之间的直接引用。
结构:
┌─────────┐
│ Mediator│◄────────┐
│+notify()│ │
└────┬────┘ │
▼ │
┌─────────┐ │
│Concrete │─────────┘
│Mediator │
└────┬────┘
│
┌────┴────┬────────┬────────┐
▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐
│Colleague│ │Colleague│ │Colleague│ │Colleague│
│ A │ │ B │ │ C │ │ D │
└────────┘ └────────┘ └────────┘ └────────┘
Python实现:
python
from abc import ABC, abstractmethod
from typing import List, Dict
# 中介者接口
class ChatMediator(ABC):
@abstractmethod
def send_message(self, message: str, sender: 'User'): pass
@abstractmethod
def add_user(self, user: 'User'): pass
# 具体中介者:聊天室
class ChatRoom(ChatMediator):
def __init__(self, room_name: str):
self.room_name = room_name
self._users: List['User'] = []
self._message_history: List[str] = []
def add_user(self, user: 'User'):
self._users.append(user)
user.mediator = self
self.broadcast(f"系统: {user.name} 加入聊天室", exclude=user)
def send_message(self, message: str, sender: 'User'):
full_msg = f"[{self.room_name}] {sender.name}: {message}"
self._message_history.append(full_msg)
# 广播给所有其他用户
self.broadcast(message, exclude=sender)
def send_private_message(self, message: str, sender: 'User', receiver: 'User'):
if receiver in self._users:
private_msg = f"[私聊] {sender.name} -> {receiver.name}: {message}"
receiver.receive(private_msg)
sender.receive(f"[私聊] 你 -> {receiver.name}: {message}")
def broadcast(self, message: str, exclude: 'User' = None):
for user in self._users:
if user != exclude:
user.receive(message)
def get_history(self) -> List[str]:
return self._message_history.copy()
# 同事类
class User(ABC):
def __init__(self, name: str):
self.name = name
self._mediator: ChatMediator = None
@property
def mediator(self) -> ChatMediator:
return self._mediator
@mediator.setter
def mediator(self, mediator: ChatMediator):
self._mediator = mediator
def send(self, message: str):
if self._mediator:
self._mediator.send_message(message, self)
@abstractmethod
def receive(self, message: str): pass
# 具体同事:普通用户
class RegularUser(User):
def receive(self, message: str):
print(f" [{self.name}] 收到: {message}")
# 具体同事:管理员(特殊权限)
class AdminUser(User):
def __init__(self, name: str):
super().__init__(name)
self._muted_users: List[str] = []
def mute(self, user_name: str):
self._muted_users.append(user_name)
self.send(f"禁言用户: {user_name}")
def receive(self, message: str):
print(f" [{self.name}] [管理员] 收到: {message}")
# 使用
print("=== 聊天室演示 ===")
room = ChatRoom("Python技术群")
alice = RegularUser("Alice")
bob = RegularUser("Bob")
charlie = AdminUser("Charlie")
room.add_user(alice)
room.add_user(bob)
room.add_user(charlie)
print("\nAlice发送消息:")
alice.send("大家好,有人用过FastAPI吗?")
print("\nBob回复:")
bob.send("用过,性能很不错!")
print("\nCharlie禁言Bob:")
charlie.mute("Bob")
print("\n历史记录:")
for msg in room.get_history():
print(f" {msg}")
应用场景:聊天室、MVC控制器、协调多个组件的复杂UI、航空管制系统
18. 备忘录模式(Memento)
意图:在不破坏封装性的前提下,捕获对象的内部状态,以便后续恢复。
结构:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Caretaker│────►│ Memento │◄─────│ Originator│
│(manager) │ │(state) │ │(create/restore)│
│ -mementos │ │(immutable) │ │
└─────────┘ └─────────┘ └─────────┘
Python实现(含窄接口/宽接口控制):
python
from abc import ABC, abstractmethod
from typing import List, Dict, Any
from copy import deepcopy
from datetime import datetime
# 备忘录(窄接口:对Caretaker可见)
class EditorMemento:
def __init__(self, state: Dict[str, Any], timestamp: str = None):
self._state = deepcopy(state)
self._timestamp = timestamp or datetime.now().isoformat()
self._name = f"备份_{self._timestamp}"
@property
def name(self) -> str:
return self._name
@property
def timestamp(self) -> str:
return self._timestamp
def get_state(self) -> Dict[str, Any]:
"""Caretaker无法访问具体状态,只能获取元信息"""
return None # 窄接口不暴露状态
# 发起人:文本编辑器
class TextEditor:
def __init__(self):
self._content = ""
self._cursor_position = 0
self._selection = None
self._font_settings = {"family": "Arial", "size": 12}
def type(self, text: str):
self._content = self._content[:self._cursor_position] + text + self._content[self._cursor_position:]
self._cursor_position += len(text)
print(f"输入: '{text}' -> 内容: '{self._content[:30]}...'")
def select(self, start: int, end: int):
self._selection = (start, end)
self._cursor_position = end
print(f"选中: {start}-{end}")
def change_font(self, family: str = None, size: int = None):
if family:
self._font_settings["family"] = family
if size:
self._font_settings["size"] = size
print(f"字体设置: {self._font_settings}")
def create_memento(self) -> EditorMemento:
"""创建备忘录(宽接口:可以访问所有状态)"""
state = {
"content": self._content,
"cursor": self._cursor_position,
"selection": self._selection,
"font": self._font_settings.copy()
}
return EditorMemento(state)
def restore(self, memento: EditorMemento):
"""从备忘录恢复(宽接口)"""
# 直接访问备忘录的内部状态(只有Originator可以这样做)
state = memento._state # Python中通过命名约定保护,实际可访问
self._content = state["content"]
self._cursor_position = state["cursor"]
self._selection = state["selection"]
self._font_settings = state["font"]
print(f"恢复到状态: {memento.name}")
def __str__(self):
return f"Editor(content='{self._content[:20]}...', cursor={self._cursor_position})"
# 负责人:历史管理器
class HistoryManager:
def __init__(self, editor: TextEditor):
self._editor = editor
self._history: List[EditorMemento] = []
self._current_index = -1
def backup(self, name: str = None):
memento = self._editor.create_memento()
if name:
memento._name = name # 重命名(Python中可以修改)
# 如果在历史中间,删除后面的历史
if self._current_index < len(self._history) - 1:
self._history = self._history[:self._current_index + 1]
self._history.append(memento)
self._current_index += 1
print(f"备份创建: {memento.name}")
def undo(self):
if self._current_index > 0:
self._current_index -= 1
memento = self._history[self._current_index]
self._editor.restore(memento)
return True
print("无法撤销:已到最初状态")
return False
def redo(self):
if self._current_index < len(self._history) - 1:
self._current_index += 1
memento = self._history[self._current_index]
self._editor.restore(memento)
return True
print("无法重做:已到最新状态")
return False
def show_history(self):
print("\n历史记录:")
for i, memento in enumerate(self._history):
marker = " <-- 当前" if i == self._current_index else ""
print(f" [{i}] {memento.name}{marker}")
# 使用
editor = TextEditor()
history = HistoryManager(editor)
print("=== 编辑文档 ===")
editor.type("Hello ")
history.backup("初始输入")
editor.type("World")
editor.select(0, 5)
history.backup("输入World并选中")
editor.change_font(family="Times", size=14)
editor.type("Python")
history.backup("修改字体并输入Python")
print(f"\n当前状态: {editor}")
print("\n=== 撤销操作 ===")
history.undo()
history.undo()
history.show_history()
print("\n=== 重做操作 ===")
history.redo()
print(f"恢复后: {editor}")
应用场景:撤销/重做功能、游戏存档、数据库事务、配置快照
19. 观察者模式(Observer)
已在前面详细展示,见第4.1节。补充Python内置支持:
python
# Python内置观察者支持:Event/Signal机制
class Event:
def __init__(self):
self._listeners = []
def connect(self, listener):
self._listeners.append(listener)
def disconnect(self, listener):
self._listeners.remove(listener)
def emit(self, *args, **kwargs):
for listener in self._listeners:
listener(*args, **kwargs)
# 使用
class DataStore:
def __init__(self):
self.data_changed = Event()
self._data = {}
def update(self, key, value):
self._data[key] = value
self.data_changed.emit(key, value)
def on_data_changed(key, value):
print(f"数据变更: {key} = {value}")
store = DataStore()
store.data_changed.connect(on_data_changed)
store.update("user", "Alice")
20. 状态模式(State)
意图:允许对象在内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
结构:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Context │─────►│ State │◄─────│Concrete │
│ -state │ │(interface)│ │ States │
│+request()│ │+handle() │ │+handle()│
└─────────┘ └─────────┘ └─────────┘
Python实现(模拟订单状态机):
python
from abc import ABC, abstractmethod
from enum import Enum, auto
class OrderStatus(Enum):
PENDING = "待支付"
PAID = "已支付"
SHIPPED = "已发货"
DELIVERED = "已送达"
CANCELLED = "已取消"
# 状态接口
class OrderState(ABC):
def __init__(self, order: 'Order'):
self.order = order
@abstractmethod
def pay(self): pass
@abstractmethod
def ship(self): pass
@abstractmethod
def deliver(self): pass
@abstractmethod
def cancel(self): pass
@property
@abstractmethod
def status(self) -> OrderStatus: pass
# 具体状态:待支付
class PendingState(OrderState):
@property
def status(self): return OrderStatus.PENDING
def pay(self):
print("支付成功!")
self.order.state = PaidState(self.order)
def ship(self):
print("错误:未支付订单不能发货")
def deliver(self):
print("错误:未支付订单不能送达")
def cancel(self):
print("订单已取消")
self.order.state = CancelledState(self.order)
# 具体状态:已支付
class PaidState(OrderState):
@property
def status(self): return OrderStatus.PAID
def pay(self):
print("错误:订单已支付")
def ship(self):
print("发货成功!")
self.order.state = ShippedState(self.order)
def deliver(self):
print("错误:订单未发货")
def cancel(self):
print("申请退款并取消订单")
self.order.state = CancelledState(self.order)
# 具体状态:已发货
class ShippedState(OrderState):
@property
def status(self): return OrderStatus.SHIPPED
def pay(self):
print("错误:订单已支付")
def ship(self):
print("错误:订单已发货")
def deliver(self):
print("送达成功!")
self.order.state = DeliveredState(self.order)
def cancel(self):
print("货物已发出,无法取消,请拒收")
# 具体状态:已送达
class DeliveredState(OrderState):
@property
def status(self): return OrderStatus.DELIVERED
def pay(self): print("错误:订单已完成")
def ship(self): print("错误:订单已完成")
def deliver(self): print("错误:订单已完成")
def cancel(self): print("错误:订单已完成,不能取消")
# 具体状态:已取消
class CancelledState(OrderState):
@property
def status(self): return OrderStatus.CANCELLED
def pay(self): print("错误:订单已取消")
def ship(self): print("错误:订单已取消")
def deliver(self): print("错误:订单已取消")
def cancel(self): print("错误:订单已取消")
# 上下文:订单
class Order:
def __init__(self, order_id: str):
self.order_id = order_id
self._state: OrderState = PendingState(self)
@property
def state(self) -> OrderState:
return self._state
@state.setter
def state(self, new_state: OrderState):
self._state = new_state
print(f" [状态变更] {self.order_id} -> {new_state.status.value}")
@property
def status(self):
return self._state.status
# 委托给状态对象
def pay(self): self._state.pay()
def ship(self): self._state.ship()
def deliver(self): self._state.deliver()
def cancel(self): self._state.cancel()
# 使用
print("=== 订单状态机演示 ===")
order = Order("ORD-2024-001")
print(f"当前状态: {order.status.value}")
order.pay() # 待支付 -> 已支付
order.ship() # 已支付 -> 已发货
order.deliver() # 已发货 -> 已送达
print("\n=== 另一个订单:取消流程 ===")
order2 = Order("ORD-2024-002")
order2.cancel() # 待支付 -> 已取消
order2.pay() # 错误:已取消
应用场景:订单状态、游戏角色状态、线程状态、网络连接状态
21. 策略模式(Strategy)
已在前面详细展示,见第4.2节。补充策略与简单工厂的对比:
python
# 策略模式 vs 简单工厂
class PaymentContext:
"""策略模式:运行时切换算法"""
def __init__(self, strategy=None):
self._strategy = strategy
def set_strategy(self, strategy):
self._strategy = strategy
def pay(self, amount):
if not self._strategy:
raise ValueError("未设置支付策略")
return self._strategy.pay(amount)
class PaymentFactory:
"""简单工厂:根据类型创建对象"""
@staticmethod
def create_payment(payment_type: str):
strategies = {
"alipay": AlipayStrategy(),
"wechat": WechatStrategy(),
"card": CardStrategy()
}
return strategies.get(payment_type)
22. 模板方法模式(Template Method)
已在前面详细展示,见第4.3节。补充钩子方法的使用:
python
from abc import ABC, abstractmethod
class DataParser(ABC):
def parse(self, filepath):
"""模板方法"""
data = self._read_file(filepath)
parsed = self._parse_data(data)
# 钩子方法:子类可选择性覆盖
if self._should_validate():
self._validate(parsed)
# 钩子方法:默认不执行,子类可覆盖
self._post_process(parsed)
return parsed
@abstractmethod
def _read_file(self, filepath): pass
@abstractmethod
def _parse_data(self, data): pass
def _should_validate(self) -> bool:
"""钩子:默认需要验证"""
return True
def _validate(self, data):
"""钩子:默认验证逻辑"""
print("执行默认验证")
def _post_process(self, data):
"""钩子:默认空实现"""
pass
class JSONParser(DataParser):
def _read_file(self, filepath):
import json
with open(filepath) as f:
return json.load(f)
def _parse_data(self, data):
return data # JSON已解析
def _post_process(self, data):
print("JSON特有后处理:转换日期格式")
class CSVParser(DataParser):
def _read_file(self, filepath):
import csv
with open(filepath) as f:
return list(csv.reader(f))
def _parse_data(self, data):
headers = data[0]
return [dict(zip(headers, row)) for row in data[1:]]
def _should_validate(self) -> bool:
return False # CSV不需要验证
23. 访问者模式(Visitor)
意图:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
结构:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Client │─────►│ Visitor │◄─────│Concrete │
│ │ │+visitA() │ │Visitors │
└─────────┘ │+visitB() │ └────┬────┘
└─────────┘ │
▲ │
│ │
┌─────────┐ │
│ Element │◄───────────┘
│+accept()│
└────┬────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
ConcreteElementA ConcreteElementB ...
+accept(visitor) +accept(visitor)
Python实现:
python
from abc import ABC, abstractmethod
from typing import List
# 访问者接口
class Visitor(ABC):
@abstractmethod
def visit_employee(self, employee: 'Employee'): pass
@abstractmethod
def visit_department(self, department: 'Department'): pass
# 元素接口
class OrganizationElement(ABC):
@abstractmethod
def accept(self, visitor: Visitor): pass
# 具体元素:员工
class Employee(OrganizationElement):
def __init__(self, name: str, salary: float, vacation_days: int):
self.name = name
self.salary = salary
self.vacation_days = vacation_days
def accept(self, visitor: Visitor):
visitor.visit_employee(self)
# 具体元素:部门(组合)
class Department(OrganizationElement):
def __init__(self, name: str):
self.name = name
self.members: List[OrganizationElement] = []
def add(self, element: OrganizationElement):
self.members.append(element)
def accept(self, visitor: Visitor):
visitor.visit_department(self)
for member in self.members:
member.accept(visitor)
# 具体访问者:薪资报告
class SalaryReportVisitor(Visitor):
def __init__(self):
self.total_salary = 0
self.report = []
def visit_employee(self, employee: Employee):
self.total_salary += employee.salary
self.report.append(f"{employee.name}: ¥{employee.salary:,.2f}")
def visit_department(self, department: Department):
self.report.append(f"\n【{department.name}部门】")
def get_report(self) -> str:
return "\n".join(self.report) + f"\n\n总计: ¥{self.total_salary:,.2f}"
# 具体访问者:休假统计
class VacationVisitor(Visitor):
def __init__(self):
self.total_vacation = 0
self.details = []
def visit_employee(self, employee: Employee):
self.total_vacation += employee.vacation_days
self.details.append(f"{employee.name}: {employee.vacation_days}天")
def visit_department(self, department: Department):
self.details.append(f"\n{department.name}:")
def get_report(self) -> str:
return "\n".join(self.details) + f"\n\n总休假天数: {self.total_vacation}天"
# 具体访问者:JSON导出(新功能,无需修改元素类)
class JSONExportVisitor(Visitor):
def __init__(self):
self.data = {"departments": []}
self.current_dept = None
def visit_employee(self, employee: Employee):
emp_data = {
"name": employee.name,
"salary": employee.salary,
"vacation": employee.vacation_days
}
if self.current_dept:
self.current_dept["employees"].append(emp_data)
def visit_department(self, department: Department):
dept_data = {"name": department.name, "employees": []}
self.data["departments"].append(dept_data)
self.current_dept = dept_data
def get_json(self) -> dict:
import json
return json.dumps(self.data, ensure_ascii=False, indent=2)
# 构建组织结构
engineering = Department("工程部")
engineering.add(Employee("张三", 30000, 10))
engineering.add(Employee("李四", 25000, 15))
sales = Department("销售部")
sales.add(Employee("王五", 20000, 12))
company = Department("总公司")
company.add(engineering)
company.add(sales)
# 使用不同访问者
print("=== 薪资报告 ===")
salary_visitor = SalaryReportVisitor()
company.accept(salary_visitor)
print(salary_visitor.get_report())
print("\n=== 休假统计 ===")
vacation_visitor = VacationVisitor()
company.accept(vacation_visitor)
print(vacation_visitor.get_report())
print("\n=== JSON导出 ===")
json_visitor = JSONExportVisitor()
company.accept(json_visitor)
print(json_visitor.get_json())
应用场景:编译器AST遍历、文档对象模型(DOM)操作、组织架构报表
第四部分:设计模式速查表与选择指南
23种模式速查表
| 模式 | 类型 | 意图 | 使用频率 |
|---|---|---|---|
| 单例 | 创建型 | 唯一实例 | ⭐⭐⭐⭐⭐ |
| 工厂方法 | 创建型 | 子类决定实例 | ⭐⭐⭐⭐⭐ |
| 抽象工厂 | 创建型 | 产品族创建 | ⭐⭐⭐⭐ |
| 建造者 | 创建型 | 分步构建 | ⭐⭐⭐⭐ |
| 原型 | 创建型 | 复制对象 | ⭐⭐⭐ |
| 适配器 | 结构型 | 接口转换 | ⭐⭐⭐⭐⭐ |
| 桥接 | 结构型 | 抽象与实现分离 | ⭐⭐⭐ |
| 组合 | 结构型 | 树形结构 | ⭐⭐⭐⭐ |
| 装饰器 | 结构型 | 动态添加职责 | ⭐⭐⭐⭐⭐ |
| 外观 | 结构型 | 简化接口 | ⭐⭐⭐⭐⭐ |
| 享元 | 结构型 | 共享细粒度对象 | ⭐⭐⭐ |
| 代理 | 结构型 | 控制访问 | ⭐⭐⭐⭐⭐ |
| 责任链 | 行为型 | 链式处理 | ⭐⭐⭐⭐ |
| 命令 | 行为型 | 请求封装 | ⭐⭐⭐⭐ |
| 解释器 | 行为型 | 语言解释 | ⭐⭐ |
| 迭代器 | 行为型 | 顺序访问 | ⭐⭐⭐⭐⭐ |
| 中介者 | 行为型 | 封装交互 | ⭐⭐⭐ |
| 备忘录 | 行为型 | 状态保存 | ⭐⭐⭐ |
| 观察者 | 行为型 | 订阅通知 | ⭐⭐⭐⭐⭐ |
| 状态 | 行为型 | 状态机 | ⭐⭐⭐⭐ |
| 策略 | 行为型 | 算法互换 | ⭐⭐⭐⭐⭐ |
| 模板方法 | 行为型 | 算法骨架 | ⭐⭐⭐⭐⭐ |
| 访问者 | 行为型 | 分离操作 | ⭐⭐⭐ |
设计模式选择决策树
遇到设计问题?
│
├─ 需要创建对象?
│ ├─ 只需要一个实例 → 单例
│ ├─ 根据不同条件创建 → 工厂方法
│ ├─ 创建过程复杂且分步 → 建造者
│ ├─ 需要产品族 → 抽象工厂
│ └─ 需要复制现有对象 → 原型
│
├─ 需要组合对象?
│ ├─ 接口不兼容 → 适配器
│ ├─ 需要树形结构 → 组合
│ ├─ 需要动态添加功能 → 装饰器
│ ├─ 需要简化复杂系统 → 外观
│ ├─ 需要大量共享对象 → 享元
│ ├─ 需要控制访问 → 代理
│ └─ 抽象和实现需要独立变化 → 桥接
│
└─ 需要处理对象交互?
├─ 一个变化通知多个 → 观察者
├─ 需要遍历集合 → 迭代器
├─ 需要撤销/重做 → 备忘录
├─ 需要状态机 → 状态
├─ 需要算法互换 → 策略
├─ 需要固定流程但步骤可变 → 模板方法
├─ 需要封装请求 → 命令
├─ 需要链式处理 → 责任链
├─ 需要封装多对象交互 → 中介者
├─ 需要给类添加新操作而不修改 → 访问者
└─ 需要解释语言 → 解释器
第五部分:Python特有的模式实现技巧
1. 使用__call__实现仿函数模式
python
class Accumulator:
def __init__(self):
self.total = 0
def __call__(self, value):
self.total += value
return self.total
acc = Accumulator()
print(acc(5)) # 5
print(acc(3)) # 8
print(acc(10)) # 18
2. 使用描述符实现属性管理
python
class ValidatedAttribute:
def __init__(self, min_value, max_value):
self.min_value = min_value
self.max_value = max_value
self.name = None
def __set_name__(self, owner, name):
self.name = name
self.storage_name = f'_validated_{name}'
def __get__(self, instance, owner):
if instance is None:
return self
return getattr(instance, self.storage_name, None)
def __set__(self, instance, value):
if not self.min_value <= value <= self.max_value:
raise ValueError(f"{self.name} must be in [{self.min_value}, {self.max_value}]")
setattr(instance, self.storage_name, value)
class Person:
age = ValidatedAttribute(0, 150)
salary = ValidatedAttribute(0, 1000000)
p = Person()
p.age = 25 # OK
p.age = 200 # ValueError
3. 使用元类实现类级别的模式
python
class AutoRegisterMeta(type):
registry = {}
def __new__(mcs, name, bases, namespace):
cls = super().__new__(mcs, name, bases, namespace)
if name != 'BasePlugin': # 排除基类
mcs.registry[name] = cls
return cls
class BasePlugin(metaclass=AutoRegisterMeta):
pass
class EmailPlugin(BasePlugin): pass
class SMSPlugin(BasePlugin): pass
print(AutoRegisterMeta.registry)
# {'EmailPlugin': <class '__main__.EmailPlugin'>, 'SMSPlugin': <class '__main__.SMSPlugin'>}
总结
本文涵盖了GoF全部23种设计模式,每种模式都包含:
- 意图与结构:明确模式要解决的问题和UML结构
- Python实现:符合Python语言特性的代码(不仅是Java的翻译)
- 实际应用场景:帮助你判断何时使用该模式
- 变体与对比:如代理的4种类型、迭代器的传统vs Pythonic实现
学习建议:
- 先掌握单例、工厂、观察者、策略、装饰器、模板方法这6个最常用的模式
- 阅读Django、Flask、Requests等优秀Python框架的源码,观察模式的真实应用
- 避免过度设计,记住:KISS原则优先于设计模式
设计模式是工具而非教条,理解它们背后的设计原则(SOLID)比死记硬背模式更重要。