Deep Modules
Deep Modules
来自 John Ousterhout《A Philosophy of Software Design》。Matt Pocock 的架构优化 skill /improve-codebase-architecture 的核心评估框架。
定义
深模块 = 小接口 + 大实现。大量行为隐藏在简洁接口后面。
┌─────────────────────┐
│ Small Interface │ ← 少量方法,简单参数
├─────────────────────┤
│ │
│ Deep Implementation│ ← 复杂逻辑隐藏其中
│ │
└─────────────────────┘
浅模块 = 大接口 + 小实现。接口几乎和实现一样复杂(反模式)。
┌─────────────────────────────────┐
│ Large Interface │ ← 方法多,参数复杂
├─────────────────────────────────┤
│ Thin Implementation │ ← 透传,没有隐藏复杂度
└─────────────────────────────────┘
关键术语体系(Pocock 精确定义)
| 术语 | 定义 | 避免使用 |
| Module | 任何有接口和实现的东西(函数/类/包/切片) | unit, component, service |
| Interface | 调用者必须知道的一切(类型+不变量+错误模式+配置) | API, signature |
| Depth | 接口处的杠杆率 — 行为量 ÷ 接口复杂度 | — |
| Seam | 接口存在的位置,行为可在此被替换 | boundary |
| Adapter | 满足 seam 处接口的具体实现 | — |
| Leverage | 调用者从深度中获得的收益 | — |
| Locality | 维护者从深度中获得的收益 — 变更/错误/知识集中在一处 | — |
删除测试
想象删除该模块。如果复杂度消失,它只是个透传。如果复杂度重新出现在 N 个调用者中,它物有所值。
深化策略
Pocock 的 /improve-codebase-architecture skill 的完整流程:
- 探索 — 用领域词汇(CONTEXT.md)+ ADR 理解现状,找"浅模块"
- HTML 报告 — 可视化 before/after 对比,推荐强度标记
- Grilling 循环 — 选定候选后进入设计讨论
- 接口设计 — 用"Design It Twice"模式,3+ 并行 subagent 生成截然不同的接口方案
依赖分类决定测试策略
| 类别 | 示例 | 测试方式 |
| In-process | 纯计算 | 直接测试,无需 adapter |
| Local-substitutable | PGLite for Postgres | 用替代品测试 |
| Remote but owned | 微服务 | Port + Adapter(生产 HTTP + 测试 in-memory) |
| True external | Stripe API | Port + Mock |
原则
- 接口是测试面 — 调用者和测试穿过同一个 seam
- 一个 adapter = 假设的 seam。两个 adapter = 真正的 seam。
- 深度是接口的属性,不是实现的属性