Skip to content
Back to skills

Deep Module Design Zh

ASecurity

深模块设计、模块接口设计、接缝(seam)放在哪、可测试性设计、找加深机会、设计两次。当用户说「这个模块接口怎么设计」「代码太碎了怎么合并成深模块」「接缝放哪」「怎么让代码更好测」「帮我设计几种不同的接口方案比较」「什么是深模块」时使用。给一套统一词汇(模块、接口、实现、深度、接缝、适配器、杠杆、局部性);深 vs 浅模块;原则:深度是接口的属性、删除测试、接口即测试面、一个适配器是假接缝两个才是真的;为可测试性设计(接受依赖、返回结果、小表面积);加深一簇浅模块时按依赖类别(进程内 / 本地可替代 / 远程自有 / 真外部)决定测试策略与端口适配器;「设计两次」并行产出 3 个以上截然不同的接口再按深度/局部性/接缝位置比较并给有主见的推荐。也覆盖「合成一个深模块」「截然不同的接口」「一堆内部函数」这类说法。改编自 Matt Pocock 的 codebase-design(MIT)。

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 13, 2026
ai-agentsgogitapi

Works with

  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 13, 2026

npx -y skills add po-et/workbuddy-skills --skill deep-module-design-zh --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Deep Module Design Zh?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Deep Module Design Zh
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/po-et-deep-module-design-zh/badge)](https://www.skillsdirectory.com/skills/po-et-deep-module-design-zh)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: deep-module-design-zh
description: 深模块设计、模块接口设计、接缝(seam)放在哪、可测试性设计、找加深机会、设计两次。当用户说「这个模块接口怎么设计」「代码太碎了怎么合并成深模块」「接缝放哪」「怎么让代码更好测」「帮我设计几种不同的接口方案比较」「什么是深模块」时使用。给一套统一词汇(模块、接口、实现、深度、接缝、适配器、杠杆、局部性);深 vs 浅模块;原则:深度是接口的属性、删除测试、接口即测试面、一个适配器是假接缝两个才是真的;为可测试性设计(接受依赖、返回结果、小表面积);加深一簇浅模块时按依赖类别(进程内 / 本地可替代 / 远程自有 / 真外部)决定测试策略与端口适配器;「设计两次」并行产出 3 个以上截然不同的接口再按深度/局部性/接缝位置比较并给有主见的推荐。也覆盖「合成一个深模块」「截然不同的接口」「一堆内部函数」这类说法。改编自 Matt Pocock 的 codebase-design(MIT)。
author: Captain
version: 0.1.1
display_name: "深模块设计(接口·接缝·可测性)"
display_name_en: "Deep Module Design (zh)"
description_zh: "用统一词汇设计深模块:小接口大实现、接缝位置、适配器、杠杆与局部性;删除测试与接口即测试面;按依赖类别加深并选测试策略;设计两次比较多个接口方案。"
description_en: "Design deep modules with a shared vocabulary: small interface, large implementation, seam placement, adapters, leverage and locality; the deletion test and interface-as-test-surface; deepen by dependency category; design it twice and compare."
tags:
  - "深模块"
  - "接口设计"
  - "接缝"
  - "seam"
  - "可测试性"
  - "适配器"
  - "设计两次"
examples_zh:
  - "这几个薄薄的 service 层能不能合成一个深模块,接缝放哪"
  - "给订单模块设计三种截然不同的接口并比较"
  - "怎么改才能不 mock 一堆内部函数就能测"
examples_en:
  - "Can these thin service layers merge into one deep module, where does the seam go"
  - "Design three radically different interfaces for the order module and compare"
  - "How do I make this testable without mocking internals"
metadata:
  { "openclaw": { "requires": { "bins": [] }, "os": ["darwin", "linux", "windows"], "emoji": "🧊" } }
---

# 深模块设计

设计**深模块**:小接口后面藏很多行为,放在干净的接缝上,通过接口可测。这套语言和原则用于任何设计或重构代码的场合。目标:调用者得到杠杆,维护者得到局部性,所有人得到可测性。

## 词汇(精确使用,别换成"组件/服务/API/边界")
- **模块**:任何有接口和实现的东西,刻意不分尺度——函数、类、包、跨层切片。避免:单元、组件、服务。
- **接口**:调用者正确使用模块必须知道的一切:类型签名,还有不变量、顺序约束、错误模式、必需配置、性能特征。避免:API、签名(太窄)。
- **实现**:模块内部的代码体。区别于**适配器**:一个东西可以是小适配器大实现(Postgres 仓储),也可以是大适配器小实现(内存 fake)。谈接缝时用"适配器",否则用"实现"。
- **深度**:接口处的杠杆——调用者(或测试)每学一单位接口能驱动多少行为。大量行为藏在小接口后是**深**,接口几乎和实现一样复杂是**浅**。
- **接缝**(Michael Feathers):不在那个地方编辑就能改变行为的位置,即模块接口所在之处。接缝放哪是独立的设计决策,与放什么在后面不同。避免:边界(与 DDD 的限界上下文冲突)。
- **适配器**:在接缝处满足接口的具体物;描述角色不描述内容。
- **杠杆**:调用者从深度得到的——每学一单位接口得到更多能力;一份实现回报 N 个调用点和 M 个测试。
- **局部性**:维护者从深度得到的——变更、bug、知识、验证集中在一处而不是散在调用者里。修一次到处都好。

## 深 vs 浅
深模块 = 小接口 + 大实现(少量方法、简单参数、复杂逻辑隐藏);浅模块 = 大接口 + 薄实现(很多方法、复杂参数、只是透传)——避免。设计接口时问:能减少方法数吗?能简化参数吗?能把更多复杂度藏进去吗?

## 原则
- **深度是接口的属性,不是实现的**。深模块内部可以由小的、可 mock、可替换的部件组成,只是它们不在接口上。模块可以有**内部接缝**(实现私有,供自己的测试用)和接口处的**外部接缝**。
- **删除测试**:想象删掉这个模块。复杂度消失 → 它只是透传;复杂度在 N 个调用者里重新出现 → 它在挣自己的饭。
- **接口即测试面**:调用者和测试跨同一道接缝。想测到接口"后面",模块大概形状不对。
- **一个适配器是假接缝,两个才是真的**:没有东西真的在接缝两侧变化就别引入接缝。

## 为可测试性设计
接受依赖而不是创建依赖(`processOrder(order, gateway)` 而不是在函数里 `new StripeGateway()`);返回结果而不是产生副作用(`calculateDiscount(cart): Discount` 而不是就地改 `cart.total`);小表面积(方法少测试少,参数少准备简单)。

## 加深一簇浅模块(按依赖类别)
1. **进程内**:纯计算、内存状态、无 I/O——总能加深,合并后直接通过新接口测,不需要适配器。
2. **本地可替代**:有本地替身的依赖(Postgres 的 PGLite、内存文件系统)——有替身就能加深,测试套件里跑替身;接缝在内部,外部接口不开端口。
3. **远程但自有**(端口与适配器):你自己的服务跨网络——在接缝定义**端口**(接口),深模块拥有逻辑,传输以**适配器**注入;测试用内存适配器,生产用 HTTP/gRPC/队列适配器。推荐句式:"在接缝定义端口,生产实现 HTTP 适配器、测试实现内存适配器,逻辑仍在一个深模块里,尽管跨网络部署。"
4. **真外部**(mock):你不控制的第三方(支付、短信)——深模块把它作为注入的端口,测试提供 mock 适配器。
接缝纪律:至少两个适配器才引入端口(通常生产 + 测试),单适配器接缝只是间接层;内部接缝不要因为测试用了就暴露到接口上。
**测试策略:替换而不是叠加**:加深后的模块接口处有了测试,浅模块上的旧单元测试就是垃圾,删掉;新测试写在加深模块的接口处;断言接口可观察的结果而不是内部状态;测试应该扛得住内部重构——实现一改测试就得改,说明测过了接口。

## 设计两次(Ousterhout)
第一个想法很少是最好的。用户想为选定的加深候选探索不同接口时:
1. **框定问题空间**(面向用户):新接口必须满足的约束;依赖及其类别;一段示意性草图把约束具体化(不是提案)。给用户看,然后立刻进第 2 步——用户边读边想,你并行工作。
2. **并行产出 3 个以上截然不同的接口**(有子代理就并行派发,没有就自己依次做但要真的不同):各带不同的设计约束——A 最小化接口(1–3 个入口,最大化每入口的杠杆);B 最大化灵活性(支持多用例与扩展);C 为最常见调用者优化(默认情况极简);D(如适用)围绕端口与适配器处理跨接缝依赖。技术简报独立于第 1 步的用户说明:文件路径、耦合细节、依赖类别、接缝后面是什么;同时使用本技能词汇与项目领域词汇。每个方案输出:接口(类型、方法、参数,加不变量、顺序、错误模式);调用示例;实现在接缝后藏了什么;依赖策略与适配器;取舍(杠杆高在哪、薄在哪)。
3. **依次呈现并比较**:让用户逐个吸收,再用文字对比——按**深度**(接口杠杆)、**局部性**(变更集中在哪)、**接缝位置**。然后给你自己的推荐:哪个最强、为什么;不同方案的元素能组合就提混合方案。要有主见——用户要的是明确的判断,不是菜单。

## 边界
不要为了"以防万一"引入端口:接缝纪律是至少两个真实适配器才值得抽出来,单适配器只是多一层间接。已经是深模块就别再拆细追求"更多小函数"——深度是接口的属性,不是文件数。讨论时不用"组件/服务/API/边界"这类词,统一用本技能词汇。设计两次不是为了拖延决策:收敛到一个有主见的推荐,不是甩给用户一份菜单。

自检:
```
- [ ] 每个接缝至少有两个真实适配器,不是猜想的未来需求
- [ ] 接口在概念上比实现小得多,调用者不需要理解内部结构
- [ ] 讨论里没有出现"组件/服务/API/边界"这类被否决的词
- [ ] 给了不少于 3 个截然不同的候选方案,并有一个明确推荐
```

## 被否决的框架
把深度定义为"实现行数 / 接口行数"(奖励往实现里灌水,我们用杠杆定义);把"接口"理解为 TS 的 interface 关键字或类的公有方法(太窄,这里包括调用者必须知道的每个事实);"边界"(与 DDD 冲突,说接缝或接口)。

---
改编自 [mattpocock/skills](https://github.com/mattpocock/skills) 的 `codebase-design`(MIT)。改动见 ATTRIBUTION.md。

Files in this skill

  • ATTRIBUTION.md1.1 KB
  • SKILL.md9.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.