| name | codebase-design |
| description (EN) | 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 更容易導覽,或另一個技能需要深模組詞彙時使用。 |
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.
精確使用這些術語——不要替換成「component」「service」「API」或「boundary」。一致的語言就是重點。
Module: anything with an interface and an implementation. Deliberately scale-agnostic: a function, class, package, or tier-spanning slice. Avoid: unit, component, service.
模組——任何有介面與實作的東西。刻意地與規模無關:一個函式、類別、套件,或橫跨層級的切片。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).
介面——呼叫者要正確使用模組所需知道的一切:型別簽名,也包括不變量、順序約束、錯誤模式、必要的設定,與效能特徵。Avoid: API、signature(太窄——它們只指型別層級的表面)。
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 repo),或大轉接器配小實作(記憶體中的假物件)。當主題是接縫時用「轉接器」;其他情況用「實作」。
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)——一個你可以不用在原地編輯就能改變行為的地方;模組介面所在的位置。接縫放哪裡本身是一個設計決策,與放在它後面的是什麼是兩回事。Avoid: boundary(與 DDD 的 bounded context 過載)。
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.
局部性——維護者從深度得到的:變更、bug、知識與驗證集中在一個地方,而不是散落在呼叫者之間。修一次,處處修好。
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:
好介面讓測試很自然:
```typescript // Testable function processOrder(order, paymentGateway) {}
// Hard to test function processOrder(order) { const gateway = new StripeGateway(); } ```
```typescript // Testable function processOrder(order, paymentGateway) {}
// Hard to test function processOrder(order) { const gateway = new StripeGateway(); } ```
```typescript // Testable function calculateDiscount(cart): Discount {}
// Hard to test function applyDiscount(cart): void { cart.total -= discount; } ```
```typescript // Testable function calculateDiscount(cart): Discount {}
// Hard to test 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 關鍵字或類別的公開方法:太窄——這裡的介面包含呼叫者必須知道的每一件事實。