| name | codebase-design |
| description | Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary. |
| 触发词 | 用于设计深模块的共享词汇表。当用户想要设计或改进模块的接口、寻找加深机会、决定接缝位置、使代码更可测试或更易于 AI 导航,或其他技能需要深模块词汇时使用。 |
Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.
Design deep modules: a lot of behaviour behind a small interface, placed at a clean seam, testable through that interface. Use this language and these principles wherever code is being designed or restructured. The aim is leverage for callers, locality for maintainers, and testability for everyone.
设计深模块:在小接口背后承载大量行为,放置在清晰的接缝处,通过该接口可测试。在任何设计或重构代码的地方使用这套语言和原则。目标是调用方的杠杆收益、维护方的局部性,以及所有人的可测试性。
Use these terms exactly — don't substitute "component," "service," "API," or "boundary." Consistent language is the whole point.
严格使用这些术语——不要替换为"组件"、"服务"、"API"或"边界"。统一的语言是整个要义所在。
Module — anything with an interface and an implementation. Deliberately scale-agnostic: a function, class, package, or tier-spanning slice. Avoid: unit, component, service.
模块——任何有接口和实现的东西。有意保持规模无关:一个函数、类、包或跨层切片。避免:单元、组件、服务。
Interface — everything a caller must know to use the module correctly: the type signature, but also invariants, ordering constraints, error modes, required configuration, and performance characteristics. Avoid: API, signature (too narrow — they refer only to the type-level surface).
接口——调用方正确使用模块所需知道的一切:类型签名,还包括不变性、顺序约束、错误模式、所需配置和性能特征。避免:API、签名(过于狭窄——它们只指类型层面的表面)。
Implementation — what's inside a module, its body of code. Distinct from Adapter: a thing can be a small adapter with a large implementation (a Postgres repo) or a large adapter with a small implementation (an in-memory fake). Reach for "adapter" when the seam is the topic; "implementation" otherwise.
实现——模块内部的东西,它的代码体。区别于适配器:一个东西可以是小适配器大实现(Postgres 仓库)或大适配器小实现(内存 fake)。当话题是接缝时用"适配器";否则用"实现"。
Depth — leverage at the interface: the amount of behaviour a caller (or test) can exercise per unit of interface they have to learn. A module is deep when a large amount of behaviour sits behind a small interface, shallow when the interface is nearly as complex as the implementation.
深度——在接口处的杠杆收益:调用方(或测试)每学习一单位接口所能调用的行为量。当大量行为位于小接口背后时,模块是深的;当接口几乎和实现一样复杂时是浅的。
Seam (Michael Feathers) — a place where you can alter behaviour without editing in that place; the location at which a module's interface lives. Where to put the seam is its own design decision, distinct from what goes behind it. Avoid: boundary (overloaded with DDD's bounded context).
接缝 (Michael Feathers)——可以在不编辑某处的情况下改变行为的地方;模块接口所在的位置。把接缝放在哪里本身就是一个设计决策,与接缝背后放什么不同。避免:边界(与 DDD 的限界上下文过载)。
Adapter — a concrete thing that satisfies an interface at a seam. Describes role (what slot it fills), not substance (what's inside).
适配器——在接缝处满足接口的具体东西。描述角色(填充什么槽位),而不是实质(里面是什么)。
Leverage — what callers get from depth: more capability per unit of interface they learn. One implementation pays back across N call sites and M tests.
杠杆收益——调用方从深度中获得的好处:每学习一单位接口获得更多能力。一个实现在 N 个调用点和 M 个测试中回馈。
Locality — what maintainers get from depth: change, bugs, knowledge, and verification concentrate in one place rather than spreading across callers. Fix once, fixed everywhere.
局部性——维护方从深度中获得的好处:变更、错误、知识和验证集中在一个地方,而不是分散在调用方之间。修一次,处处修复。
Deep module = small interface + lots of implementation:
深模块 = 小接口 + 大量实现:
┌─────────────────────┐
│ Small Interface │ ← Few methods, simple params
├─────────────────────┤
│ │
│ Deep Implementation│ ← Complex logic hidden
│ │
└─────────────────────┘┌─────────────────────┐
│ Small Interface │ ← Few methods, simple params
├─────────────────────┤
│ │
│ Deep Implementation│ ← Complex logic hidden
│ │
└─────────────────────┘Shallow module = large interface + little implementation (avoid):
浅模块 = 大接口 + 少量实现(避免):
┌─────────────────────────────────┐
│ Large Interface │ ← Many methods, complex params
├─────────────────────────────────┤
│ Thin Implementation │ ← Just passes through
└─────────────────────────────────┘┌─────────────────────────────────┐
│ Large Interface │ ← Many methods, complex params
├─────────────────────────────────┤
│ Thin Implementation │ ← Just passes through
└─────────────────────────────────┘When designing an interface, ask:
设计接口时,问:
Good interfaces make testing natural:
好的接口让测试变得自然:
// Testable
function processOrder(order, paymentGateway) {}
// Hard to test
function processOrder(order) {
const gateway = new StripeGateway();
}// 可测试
function processOrder(order, paymentGateway) {}
// 难测试
function processOrder(order) {
const gateway = new StripeGateway();
}// Testable
function calculateDiscount(cart): Discount {}
// Hard to test
function applyDiscount(cart): void {
cart.total -= discount;
}// 可测试
function calculateDiscount(cart): Discount {}
// 难测试
function applyDiscount(cart): void {
cart.total -= discount;
}interface keyword or a class's public methods: too narrow — interface here includes every fact a caller must know.interface 关键字或类的公开方法:太过狭窄——此处的接口包括调用方必须知道的每个事实。