14.医生手册总结索引
# 14.医生手册总结索引
本篇定位:附录篇 · 全专栏的"医生手册"——三视角带走清单 + 病案编号全表 + 术式总索引。
剧情节点:90 天诊疗结束——老陈把整份《代码医院手册》交到小李手里,说了这一部剧最后一句话:"下一次接盘的人不是小李,而是读了这本书的你。"
本篇病人:全部——本篇不再引入新病人,而是把 13 篇的所有病案、手法、清单汇编成可反复查阅的手册。
承接经典:《代码整洁之道》Ch17 味道清单 / Fowler《重构》附录:手法索引 / Feathers《修改代码的艺术》最后一章:小结。
本篇病案编号范围:全表汇编(N/F/C/E/T/A/D/R 全系列 · 约 100+ 条)
# 目录介绍
# 1. 手册序言
# 1.1 90 天回顾
Day 90 早晨,"代码医院"办公室。窗外阳光透过百叶窗,照在老陈电脑屏幕上。屏幕左边是 OrderMonolith 的 Sonar 面板(现在全绿),右边是 NextDaySvc 的 Quality Dashboard。
小李、老王、小张、小周、小陆围坐一圈,桌上摆着一份厚厚的 A4 打印稿,封面上老陈用马克笔写着六个字:
《代码医院手册》
这 90 天他们一起走过的路:
| 阶段 | 时间 | 关键篇章 | 关键交付 |
|---|---|---|---|
| 急诊科开张 | Day 1-40 | 01-06 篇 | 病例登记 + 遗留急救 |
| 影像检验 | Day 41-60 | 07-09 篇 | 度量 + 覆盖率 + 债务 |
| 外科与康复 | Day 61-85 | 10-12 篇 | 重构 + 测试 + CR |
| 预防医学 | Day 86-116 | 13 篇 | 新系统免疫力 |
| 手册汇编 | Day 117 | 14 篇(本篇) | 总索引 + 传承 |
沈总看着这张时间轴,感慨了一句:
"我们花 90 天,把'代码越写越烂'这个千古难题,变成了一份可以复制的手册。"
# 1.2 手册如何使用
本篇不是新知识——它是一份索引 + 反查工具。使用姿势:
姿势 1:按痛点反查
- 你正在被"函数太长"困扰 → 看 § 2.2 F 系列 → 找到 F03 → 跳到第 3 篇《函数与职责》
- 你的团队 lgtm 率高 → 看 § 2.8 R 系列 → R01 → 跳到第 12 篇《代码审查文化》
- 你要开新项目 → 直接看 § 5.3 + 第 13 篇《新系统免疫力》
姿势 2:按角色带走
- 你是初中级 → 只看 § 4.1 住院医 40 条
- 你是资深 → 看 § 4.2 主治 30 条
- 你是架构师/CTO → 看 § 4.3 主任 20 条
姿势 3:按经典书目补课
- § 8 推荐 15 本经典 → 按初/中/高分层阅读
关键洞察:这不是一本"从头读到尾"的书——它是床头随时翻的工具书。
# 2. 病案编号全表
# 2.1 命名类十五条
来源:第 2 篇《命名与意图》+ 全专栏散落。
| 编号 | 名称 | 危险等级 | 治疗手段 |
|---|---|---|---|
| N01 | 一字母变量(a / x) | ★★★★☆ | Rename Variable |
| N02 | 无意义名(data / info / temp) | ★★★★★ | Reveal Intent |
| N03 | 匈牙利表示法遗物(strName) | ★★☆☆☆ | Rename Variable |
| N04 | 缩写不共识(usrMgr) | ★★★☆☆ | 团队词典 |
| N05 | 布尔无 is/has 前缀 | ★★★☆☆ | 加谓词前缀 |
| N06 | 类名过于宽泛(Manager / Helper) | ★★★★☆ | Split by Responsibility |
| N07 | 方法名与实现不符 | ★★★★★ | Rename Method |
| N08 | 反义词错用(start / end vs begin / stop) | ★★★☆☆ | 团队词典 |
| N09 | 复数与单数混乱 | ★★★☆☆ | 命名规则 |
| N10 | 编码相关的技术词入侵领域(OrderJpaDto) | ★★★★☆ | 分层 DTO |
| N11 | 缩写歧义(os = OperatingSystem or orderStatus?) | ★★★☆☆ | 团队词典 |
| N12 | 类型名与业务名混用 | ★★★☆☆ | Rename |
| N13 | 布尔取反命名(!isNotDeleted) | ★★★★☆ | 双重否定消除 |
| N14 | 时间单位缺失(timeout=5000) | ★★★★★ | 后缀单位(timeoutMs) |
| N15 | 无量词泛化(list, map) | ★★★☆☆ | 加集合成员语义(activeOrders) |
# 2.2 函数类二十条
来源:第 3 篇《函数与职责》。
| 编号 | 名称 | 危险等级 | 治疗手段 |
|---|---|---|---|
| F01 | 函数超长(> 30 行) | ★★★★★ | Extract Function |
| F02 | 参数过多(> 4 个) | ★★★★☆ | Introduce Parameter Object |
| F03 | 布尔参数 | ★★★★☆ | Replace with Enum / Split Method |
| F04 | 副作用不明(同时改多个状态) | ★★★★★ | Separate Query from Modifier |
| F05 | 命令与查询混用 | ★★★★☆ | CQS |
| F06 | 深嵌套 > 3 层 | ★★★★★ | Guard Clauses / Early Return |
| F07 | 多返回类型(成功 T / 错误 null / 异常) | ★★★★☆ | Result Type / Option |
| F08 | 静态方法承担业务 | ★★★☆☆ | Introduce Class |
| F09 | 大 switch case | ★★★★☆ | Replace with Polymorphism |
| F10 | 参数类型不明确(Object) | ★★★★☆ | Introduce Type |
| F11 | 输出参数 | ★★★★☆ | Return Value |
| F12 | 隐性依赖时间 / 随机 | ★★★★★ | Inject Clock / Random |
| F13 | 复杂默认值(内联复杂对象构造) | ★★★☆☆ | Extract Factory |
| F14 | 无返回值的多态方法 | ★★★☆☆ | Return This / Builder |
| F15 | 副效应嵌入 getter | ★★★★★ | Split Query from Command |
| F16 | 全局变量修改 | ★★★★★ | Introduce Class Field / Inject |
| F17 | 隐式转换(String → int 未校验) | ★★★★☆ | Explicit Parsing + Guard |
| F18 | 函数没有单元测试可行性 | ★★★★☆ | Extract to Pure Function |
| F19 | Getter/Setter 泛滥 | ★★★☆☆ | Tell, Don't Ask |
| F20 | Reflection 滥用 | ★★★★☆ | 用接口 + 策略模式替代 |
# 2.3 C 系列类对象
来源:第 5 篇《条件与多态》+ 第 6 篇《遗留代码急救》+ 第 13 篇。
| 编号 | 名称 | 危险等级 | 治疗手段 |
|---|---|---|---|
| C01 | God Class(> 500 行) | ★★★★★ | Extract Class |
| C02 | Feature Envy(方法过度访问他类字段) | ★★★★☆ | Move Method |
| C03 | Data Class(只有 getter/setter) | ★★★☆☆ | Move Behavior |
| C04 | Primitive Obsession(原始类型痴迷) | ★★★★☆ | Value Object |
| C05 | 巨型继承树(> 4 层) | ★★★★☆ | Prefer Composition |
| C06 | Shotgun Surgery(改一处要动 N 处) | ★★★★★ | Move + Extract |
| C07 | Circular Dependency(循环依赖) | ★★★★★ | 依赖反转 |
| C08 | Static + Singleton 组合病 | ★★★★☆ | DI + Interface |
| C09 | 空构造 + Setter 组装 | ★★★☆☆ | Builder / Immutable |
| C10 | 抽象与实现不一致(Interface Segregation 违反) | ★★★★☆ | 拆接口 |
| C11 | Mutable State(可变共享状态) | ★★★★★ | Immutable / Actor |
| C12 | Bloated Constructor(构造 > 6 参数) | ★★★★☆ | Builder |
| C13 | Class 依赖框架细节(extends HttpServlet) | ★★★☆☆ | 依赖反转 |
| C14 | 用继承实现代码复用(而非多态) | ★★★★☆ | Composition |
| C15 | 用 if 判断类型 | ★★★★☆ | Polymorphism |
| C16 | 存储与业务耦合(Entity 是 Domain) | ★★★★★ | 分层 DTO |
| C17 | 泛型滥用(Generic Chain 长于 3 层) | ★★★☆☆ | 简化设计 |
| C18 | Package by Layer 无边界 | ★★★★☆ | Package by Feature |
# 2.4 E 系列错误
来源:第 4 篇《错误与边界》。
| 编号 | 名称 | 危险等级 | 治疗手段 |
|---|---|---|---|
| E01 | 吞异常(catch(Exception e){}) | ★★★★★ | 至少 log + rethrow / 处理 |
| E02 | Checked → Unchecked 全转(丢上下文) | ★★★★☆ | 保留 cause |
| E03 | 用异常做流程控制 | ★★★★☆ | Result / Option |
| E04 | 全局 try-catch 大网 | ★★★★☆ | 就近 catch |
| E05 | 无重试 / 熔断 | ★★★★★ | Resilience4j / Polly |
| E06 | 无超时(默认无限等待) | ★★★★★ | 显式 timeout |
| E07 | 边界不校验(外部输入直接落库) | ★★★★★ | 边界层校验 |
| E08 | 错误码泄漏内部实现(SQLException: near ") | ★★★★☆ | 转译为业务错误码 |
| E09 | 无 traceId 上下文 | ★★★★☆ | MDC / trace 中间件 |
| E10 | 事务边界与异常边界错位 | ★★★★☆ | 明确 @Transactional 域 |
# 2.5 测试类十二条
来源:第 8 篇《测试覆盖真相》+ 第 11 篇《测试保命之术》。
| 编号 | 名称 | 危险等级 | 治疗手段 |
|---|---|---|---|
| T01 | 覆盖率假象 78% 但仅测 Getter | ★★★★★ | 断言密度 + PIT |
| T02 | 断言弱(assertTrue(result != null)) | ★★★★☆ | AssertJ 精确断言 |
| T03 | Test 命名反模式(test1) | ★★★☆☆ | should_xxx_when_yyy |
| T04 | 一个测试多个断言(AAA 违反) | ★★★☆☆ | Split Test |
| T05 | 用真实数据库慢测(未 Testcontainers) | ★★★★☆ | Testcontainers / TestFixtures |
| T06 | Sleep + assertion(时间敏感) | ★★★★★ | Awaitility / Fake Clock |
| T07 | 无法写测(依赖太紧) | ★★★★☆ | 依赖反转 |
| T08 | Mock 过度(连 String 都 mock) | ★★★★☆ | Classical + Fake |
| T09 | Mock 脆弱(每改一处测试全崩) | ★★★★☆ | 测行为不测实现 |
| T10 | 集成契约漂移(consumer 不知 provider 变了) | ★★★★★ | Pact 契约测试 |
| T11 | Flaky 测试无治理 | ★★★★★ | 四大根因分类 + SLO |
| T12 | 测试代码腐化(无 formatter 不重构) | ★★★☆☆ | 同源代码标准 |
# 2.6 架构类十五条
来源:第 7 篇《静态分析度量》+ 第 13 篇《新系统免疫力》。
| 编号 | 名称 | 危险等级 | 治疗手段 |
|---|---|---|---|
| A01 | 圈复杂度 > 15 | ★★★★★ | 拆函数 / 策略 |
| A02 | 认知复杂度 > 15 | ★★★★★ | 早返 / 抽方法 |
| A03 | 高耦合(Efferent > 20) | ★★★★☆ | 引入接口 / DIP |
| A04 | Package 循环依赖 | ★★★★★ | 分层反转 |
| A05 | 无门禁(Sonar 未接入) | ★★★★☆ | Clean as You Code |
| A06 | 无测试金字塔(倒三角) | ★★★★☆ | 80/15/5 目标 |
| A07 | 无观测 | ★★★★★ | traceId + metric + 日志 |
| A08 | 无 ADR | ★★★★☆ | ADR 模板 |
| A09 | 无 Runbook | ★★★★☆ | Ops 手册 |
| A10 | 无灰度/回滚 | ★★★★★ | Feature Toggle + 回滚脚本 |
| A11 | 新系统无边界大类 | ★★★★★ | Clean Architecture 4 层 |
| A12 | DTO 透传 | ★★★★☆ | 分层 DTO + MapStruct |
| A13 | 决策无 ADR | ★★★☆☆ | ADR + Git 归档 |
| A14 | Day 1 观测缺失 | ★★★★★ | 观测最小闭环 |
| A15 | 假测试(Mock 无断言) | ★★★★☆ | 金字塔 + PIT + Testcontainers |
# 2.7 D 系列技术债
来源:第 9 篇《技术债量化》。
| 编号 | 名称 | 危险等级 | 治疗手段 |
|---|---|---|---|
| D01 | 债无度量 | ★★★★☆ | SQALE Debt Ratio |
| D02 | 债不分类 | ★★★★☆ | Fowler 四象限 |
| D03 | 债无优先级 | ★★★★☆ | 本金 + 利息模型 |
| D04 | 无还债节奏 | ★★★★★ | 每冲刺 20% 还债预算 |
| D05 | 债与业务无对齐 | ★★★★☆ | 机会成本模型(省/赚/避) |
| D06 | KPI 化度量(Goodhart) | ★★★★☆ | 多维度 + 定性回顾 |
| D07 | 只看 Sonar 不看实际影响 | ★★★☆☆ | 加事故映射 |
| D08 | 无债务地图 | ★★★☆☆ | 热点图 + 优先级排序 |
| D09 | 债务不进 backlog | ★★★★☆ | 债务 Issue = 一等公民 |
| D10 | 没有"债务墓地"归档 | ★★★☆☆ | 已还债项归档展示 |
# 2.8 R 系列审查
来源:第 12 篇《代码审查文化》。
| 编号 | 名称 | 危险等级 | 治疗手段 |
|---|---|---|---|
| R01 | 橡皮图章 lgtm | ★★★★★ | 卡点清单 + 强制文字意见 |
| R02 | 超大 PR(> 400 行 diff) | ★★★★☆ | 单 PR 上限 + 拆分工具 |
| R03 | 马拉松 PR(挂 > 3 天) | ★★★☆☆ | 24h SLA + PR 站会 |
| R04 | 拳击场评审(意见带情绪) | ★★★★★ | 三句式 + 分离人与代码 |
| R05 | 形式主义 CR(只挑格式) | ★★★★☆ | Linter 自动化 + 人审逻辑 |
| R06 | 无 PR 描述 | ★★★☆☆ | PR 模板四段 |
| R07 | 无门禁(CI 可绕过) | ★★★★☆ | pre-commit + branch protection |
| R08 | CR 无度量 | ★★★☆☆ | 度量看板 + 每周复盘 |
病案总计:108 条(N15 + F20 + C18 + E10 + T12 + A15 + D10 + R08)。这就是《代码疾病 ICD 手册》。
# 2.9 一句话回顾
108 条病案编号,是本专栏最扎实的资产——每一条都对应一次可复现的治疗动作。
# 2.10 核心要点
- N/F/C/E/T/A/D/R 八大前缀覆盖八类病灶
- 每条编号都可被 CR 引用与自动化检测
- 编号让团队沟通从'感觉'升级为'触发'
# 2.11 带走清单
- [ ] 八大编号表贴到 CR 模板
- [ ] 为最常出现的 10 条编号写检测规则
- [ ] 每季度出一次编号命中率报表
# 3. 手法总索引
来源:第 10 篇《重构十八招》。
# 3.1 基础 6 招
| 编号 | 手法 | 场景 | IDEA 快捷键 |
|---|---|---|---|
| R01 | Rename | 命名不当 | Shift+F6 |
| R02 | Extract Function | 函数过长 | Ctrl+Alt+M |
| R03 | Inline Function | 无谓间接 | Ctrl+Alt+N |
| R04 | Extract Variable | 表达式复杂 | Ctrl+Alt+V |
| R05 | Introduce Parameter Object | 参数过多 | Ctrl+Alt+P → Object |
| R06 | Move Method | Feature Envy | F6 |
# 3.2 进阶 6 招
| 编号 | 手法 | 场景 | 说明 |
|---|---|---|---|
| R07 | Replace Conditional with Polymorphism | 大 switch/if | 策略模式 |
| R08 | Replace Magic Number with Named Constant | 魔法数字 | Enum / static final |
| R09 | Introduce Assertion | 前置条件不清 | Guard clauses |
| R10 | Replace Temp with Query | 中间变量泛滥 | 表达式 |
| R11 | Split Loop | 循环多职责 | 拆循环 |
| R12 | Preserve Whole Object | 参数字段爆炸 | 传对象 |
# 3.3 高级 6 招
| 编号 | 手法 | 场景 | 说明 |
|---|---|---|---|
| R13 | Replace Type Code with Class | 类型码 | Value Object |
| R14 | Replace Constructor with Factory Method | 构造复杂 | Factory |
| R15 | Extract Class | God Class | 拆类 |
| R16 | Change Reference to Value | 值语义 | Immutable |
| R17 | Move Field | 数据错位 | 移字段 |
| R18 | Extract Superclass / Interface | 提炼抽象 | 接口设计 |
五大组合拳(跨招):
- 抽方法组合拳:R04 → R02 → R01(提变量 → 提方法 → 改名)
- 多态改写组合拳:R08 → R13 → R07(去魔法值 → 类型码 → 多态)
- God Class 拆解组合拳:R06 → R15 → R17(移方法 → 拆类 → 移字段)
- Data Class 复活组合拳:R02 → R06 → 移行为
- 接口抽象组合拳:R18 → R14 → 依赖反转
# 3.4 一句话回顾
18 招手法按'基础 / 进阶 / 高级'分层,是从'能改'到'敢改'再到'常改'的成长阶梯。
# 3.5 核心要点
- 基础 6 招决定入行速度
- 进阶 6 招决定质量上限
- 高级 6 招决定架构演进能力
# 3.6 带走清单
- [ ] 每周挑 1 招重点练习
- [ ] IDE 重构快捷键熟记于心
- [ ] 把手法编号与病案对照贴到工位
# 4. 三视角清单汇
# 4.1 住院医四十条
A. 命名(8 条)
- ☐ 用 Reveal Intent 命名(不用
data/temp) - ☐ 布尔加 is/has/can 前缀
- ☐ 时间/长度加单位后缀(
timeoutMs,distanceMeters) - ☐ 类名带业务角色(
OrderPaymentGateway而非Manager) - ☐ 复数与单数遵守团队词典
- ☐ 不用双重否定
- ☐ 缩写仅限业内公认(
URL,HTTPOK;usrMgrNO) - ☐ 拒绝匈牙利表示法(
strXxx)
B. 函数(10 条) 9. ☐ 函数 ≤ 30 行 10. ☐ 参数 ≤ 4 个,多则打包 11. ☐ 布尔参数拆方法或用 Enum 12. ☐ 早返 / 守卫子句代替嵌套 13. ☐ 副作用与查询分离(CQS) 14. ☐ 深嵌套 ≤ 3 层 15. ☐ 时间/随机 → 注入 Clock/Random 16. ☐ 用 Result / Option 而非 null / exception 做流程 17. ☐ 一个函数一件事 18. ☐ 参数类型明确,禁用裸 Object
C. 测试(12 条)
19. ☐ 每个 PR 新代码单测覆盖 ≥ 80%
20. ☐ 命名:should_xxx_when_yyy
21. ☐ AAA 结构(Arrange/Act/Assert)
22. ☐ 一测一断言主线
23. ☐ AssertJ 精确断言(不用 assertTrue(!= null))
24. ☐ 边界与异常路径必测
25. ☐ 用 Testcontainers 而非 H2
26. ☐ Awaitility 代替 Sleep
27. ☐ Mock 有度(不 mock String / List)
28. ☐ 测行为不测实现
29. ☐ Flaky 立即隔离
30. ☐ 变异分数 ≥ 0.7
D. 提 PR 与 CR(10 条) 31. ☐ PR ≤ 400 行 diff,超必拆 32. ☐ PR 模板四段:Why / How / Testing / Risk 33. ☐ commit 分主题(feat/fix/refactor/test) 34. ☐ 本地跑通所有测试再推 35. ☐ 无 println / TODO / 死代码 36. ☐ formatter 已跑(spotless/prettier/black) 37. ☐ CR 意见分级:nit / consider / must-fix 38. ☐ 意见附方案 39. ☐ 冲突走"原则 → 数据 → 仲裁"三步 40. ☐ 24h 内互相首评
# 4.2 主治三十条
A. 结构与边界(10 条)
- ☐ Package by Feature,不 by Layer
- ☐ 分层架构 4 层:Adapter/Application/Domain/Infra
- ☐ 依赖方向:外层 → 内层
- ☐ Domain 定义接口,Infra 实现
- ☐ 用 MapStruct 转 DTO / Command / Entity
- ☐ 拒绝 God Class(> 300 行 → 拆)
- ☐ 拒绝循环依赖(Sonar 拦)
- ☐ 值对象取代原始类型(Primitive Obsession)
- ☐ 组合优先于继承
- ☐ 领域事件驱动扩展点
B. 测试策略(8 条) 11. ☐ 金字塔占比 80/15/5 12. ☐ Testcontainers 隔离 13. ☐ PIT 变异测试 + Clean as You Code 14. ☐ Pact 契约测试双端 15. ☐ Test 替身五分法(Meszaros) 16. ☐ Flaky 治理 SLO 化 17. ☐ 集成测试有 seeded fixture 18. ☐ 性能测试基线化
C. CR 与门禁(6 条) 19. ☐ 60 条 CR 卡点,按 PR 类型抽取 20. ☐ CODEOWNERS 定核心模块 owner 21. ☐ CI required checks 六项 22. ☐ Branch protection 2 approval 23. ☐ pre-commit 三件套:format/lint/secret 24. ☐ CR 度量看板:lgtm/首评 SLA/意见数
D. 演进(6 条) 25. ☐ API 五规则:向后兼容/版本/幂等/错误码/OpenAPI 26. ☐ 数据迁移 up/down 均有 27. ☐ Feature Toggle 每重要变更 28. ☐ ADR 记录关键决策 29. ☐ 遗留集成走防腐层 30. ☐ 观测:traceId + metric + 日志
# 4.3 主任二十条
A. 度量与治理(8 条)
- ☐ SQALE Debt Ratio 每周
- ☐ Sonar Clean as You Code 门禁
- ☐ 覆盖率 + 断言密度 + PIT 三合一
- ☐ Fowler 四象限治债
- ☐ 事故 → 债务 双向映射
- ☐ 品质预算:SLO + Error Budget
- ☐ Goodhart 陷阱回避(多维度)
- ☐ 度量对齐业务(省/赚/避)
B. 组织与传承(8 条) 9. ☐ CR 是日常工作(≥ 20% 工时) 10. ☐ 24h 首评 SLA 11. ☐ CR Champion + 结对 CR 12. ☐ 每季度评审礼仪培训 13. ☐ 新人 30 天品质训练营 14. ☐ 面试筛品质基因 15. ☐ ADR / Postmortem / 工坊三仪式 16. ☐ 品质高光周报
C. 文化与哲学(4 条) 17. ☐ 分离人与代码 18. ☐ 品质是时间的复利 19. ☐ 免疫力 > 治疗力 20. ☐ 组织即架构(康威定律回扣)
# 4.4 一句话回顾
三视角清单不是三本读物,而是同一段代码的三种深度切面。
# 4.5 核心要点
- 住院医清单让 PR 今日就能上手
- 主治清单让设计有据可依
- 主任清单让组织与文化落地
# 4.6 带走清单
- [ ] 按身份选择自己的清单
- [ ] 至少'偷读'一次上一层清单
- [ ] 每季度做一次身份自检
# 5. 九十天时间轴
# 5.1 急诊科四十天
| 日期 | 里程碑 | 关联篇章 |
|---|---|---|
| Day 1 | 医院开张,OrderMonolith 入院登记 | 01.代码医院导论 |
| Day 5 | 圈复杂度扫描:max 42,触发红色警报 | 01 |
| Day 8 | 命名混战:78% 类含 Manager/Helper | 02.命名与意图 |
| Day 12 | 函数长度中位数 145 行 | 03.函数与职责 |
| Day 18 | 错误处理审计:24 处吞异常 | 04.错误与边界 |
| Day 25 | if-else 深嵌套:max 7 层 | 05.条件与多态 |
| Day 30 | Feathers 特征测试首批 10 个 | 06.遗留代码急救 |
| Day 40 | 遗留急救完成,进入影像检验期 | 06 |
# 5.2 影像检验二十天
| 日期 | 里程碑 | 关联篇章 |
|---|---|---|
| Day 41 | Sonar Server 部署 | 07.静态分析度量 |
| Day 46 | Clean as You Code 门禁生效 | 07 |
| Day 47 | 覆盖率 78% 真相揭穿 | 08.测试覆盖真相 |
| Day 52 | PIT 变异测试首次运行:分数 0.36 | 08 |
| Day 53 | 技术债量化:SQALE Debt Ratio 8.2% | 09.技术债量化 |
| Day 60 | 与老板谈判成功,20% 还债预算获批 | 09 |
# 5.3 外科康复三十天
| 日期 | 里程碑 | 关联篇章 |
|---|---|---|
| Day 61 | 重构十八招启动 | 10.重构十八招 |
| Day 70 | calculatePrice 四轮重构完成 | 10 |
| Day 71 | PaymentGate 重构血案 | 11.测试保命之术 |
| Day 78 | Testcontainers + Pact + Flaky 治理完成 | 11 |
| Day 79 | lgtm 事件爆发,47 万损失 | 12.代码审查文化 |
| Day 85 | CR 三层门禁 + 60 卡点上线 | 12 |
| Day 86 | NextDaySvc 立项 | 13.新系统免疫力 |
| Day 90 | OrderMonolith 交接,全绿谢幕 | 13 |
| Day 116 | NextDaySvc 30 天中期健康检查 | 13 |
| Day 117 | 手册汇编 | 14(本篇) |
# 5.4 一句话回顾
90 天时间轴是本书最值钱的一份'剧本'——它证明重构是可复现的工程,不是玄学。
# 5.5 核心要点
- 急诊科 40 天 · 影像 20 天 · 外科 30 天
- 节奏比速度更重要,节点比总量更关键
- 每一阶段都有明确的可交付物
# 5.6 带走清单
- [ ] 为团队画一份 30/60/90 时间轴
- [ ] 每阶段设置 1 个可交付里程碑
- [ ] 每周做一次节奏对齐
# 6. 度量对照大表
# 6.1 圈复杂度前后对比
| 模块 | Day 1(入院) | Day 90(出院) | 目标 | 变化 |
|---|---|---|---|---|
| OrderService.processOrder | 42 | 8 | ≤ 10 | -81% ✅ |
| CouponVerifier.apply | 18 | 5 | ≤ 10 | -72% ✅ |
| PaymentGate.execute | 27 | 9 | ≤ 10 | -67% ✅ |
| PriceCalculator.calculate | 33 | 6 | ≤ 10 | -82% ✅ |
| 全库 max | 42 | 12 | ≤ 15 | -71% ✅ |
| 全库 avg | 8.7 | 3.2 | ≤ 5 | -63% ✅ |
# 6.2 覆盖率与断言密度
| 指标 | Day 47(真相日) | Day 90 | 目标 | 变化 |
|---|---|---|---|---|
| 行覆盖率 | 78% | 86% | ≥ 80% | +8pp |
| 分支覆盖率 | 31% | 74% | ≥ 70% | +43pp ✅ |
| 断言密度(asserts/test) | 0.4 | 3.8 | ≥ 2 | +8.5x ✅ |
| PIT 变异分数 | 0.36 | 0.78 | ≥ 0.7 | +117% ✅ |
| Flaky 测试率 | 12% | 0.8% | ≤ 1% | -93% ✅ |
# 6.3 事故率与 MTTR
| 指标 | Day -30 to 0(治疗前) | Day 60-90(治疗后) | 目标 | 变化 |
|---|---|---|---|---|
| P1 事故(月) | 4 | 0 | ≤ 1 | -100% ✅ |
| P2 事故(月) | 11 | 2 | ≤ 3 | -82% ✅ |
| MTTR(分钟) | 187 | 24 | ≤ 30 | -87% ✅ |
| 生产 hotfix 数 | 24 | 3 | ≤ 5 | -88% ✅ |
| Change Failure Rate | 32% | 6% | ≤ 15% | -81% ✅ |
沈总看到这三张表,第一次在办公室为老陈鼓掌。
# 6.4 一句话回顾
度量对照大表,是把'我们变好了'从口号变成图表的证据链。
# 6.5 核心要点
- 圈复杂度 / 覆盖率 / 事故率是三根基础曲线
- 有基线才有对照,有对照才有说服力
- 度量必须可复现、可回溯
# 6.6 带走清单
- [ ] 三张曲线粘到会议室墙
- [ ] 度量数据接入研发看板
- [ ] 每季度出一次对照报表
# 7. 12 大设计哲学
# 7.1 命名即契约
命名不是标注,是承诺。当你给一个变量命名 activeOrders,你在向未来阅读者承诺:这个集合只包含处于激活状态的订单。破坏命名 = 违约。
# 7.2 函数即抽象
一个函数是一层抽象。函数名是"意图层",函数体是"实现层"。如果读者需要读完函数体才能懂函数名,说明抽象失败(Uncle Bob)。
# 7.3 边界即防线
系统的健康在于边界的健康。每一次外部输入都是一次潜在攻击。边界层承担校验、转换、防腐三重职责。内部越干净,边界必须越严。
# 7.4 测试即凭证
测试不是"跑起来",是给未来的自己开的信任凭证。断言强度 = 凭证的可信度。变异测试就是"信任审计"。
# 7.5 重构即呼吸
**重构不是重写。它是软件的呼吸——**每天做一点,让代码保持弹性。Kent Beck 说"Make the change easy, then make the easy change"——先重构让改动变简单,再改动。
# 7.6 度量即语言
度量是与老板对话的通用语言。工程师用圈复杂度、老板听不懂;工程师用"每季度多花 400 万人力",老板立即明白。翻译能力是资深工程师的核心素养。
# 7.7 债务即成本
Ward Cunningham 首创"技术债"隐喻,Fowler 补上四象限。债务不可怕,可怕的是不还。审慎的债 = 战略工具;鲁莽的债 = 慢性自杀。
# 7.8 审查即传承
CR 的价值 60% 是拦 Bug,40% 是知识流动 + 文化沉淀。每一条 CR 意见,都是一次跨人的教学。团队的品质天花板 = 团队 CR 的中位数。
# 7.9 文化即免疫
技术护栏可以复制,品质文化只能培养。工具只是外骨骼,文化才是内在免疫系统。当每个人都自然写测试、自然分层、自然 CR,团队就有了终身免疫力。
# 7.10 组织即架构
康威定律(Conway's Law)铁律:软件架构会长成组织沟通结构的样子。想让代码解耦,先让团队解耦。反过来,想改团队,先动架构(Reverse Conway)。
# 7.11 演进即设计
没有一次到位的设计,只有持续演进的设计。Martin Fowler 说 "Evolutionary Architecture"——架构不是画出来的,是长出来的。ADR 就是这棵树的年轮。
# 7.12 品质即时间
这是全专栏的终极哲学:
品质工程的本质,是在"当下多花 20%"与"未来省下 200%"之间做时间贴现。
不做品质的团队,本质是把未来的时间抵押给现在的速度——债主是未来的自己。
Barry Boehm 的缺陷成本曲线是这个哲学最有力的证据:编码期修 1 元,生产期修 100 元。品质工程的所有努力,都是把成本"前移到廉价区间"。
# 7.13 一句话回顾
12 大设计哲学,是把 14 篇诊疗记录浓缩到墙上的 12 个短句。
# 7.14 核心要点
- 哲学是行动的锚点,不是标语
- 每条哲学都对应一个具体动作
- 哲学之间彼此呼应,构成完整心法
# 7.15 带走清单
- [ ] 把 12 条哲学打印贴到工位
- [ ] 月度选 1 条做团队复盘
- [ ] 新人入职必读 12 大哲学
# 8. 经典书目推荐路径
# 8.1 初级推荐 5 本
- 《代码整洁之道》 - Robert C. Martin:命名/函数/类基础准则
- 《程序员修炼之道》 - Andrew Hunt & David Thomas:工程哲学入门
- 《单元测试的艺术》 - Roy Osherove:从 0 开始学写单测
- 《卓有成效的程序员》 - Neal Ford:日常效率工具
- 《Head First 设计模式》 - Eric Freeman:可视化设计模式
# 8.2 高级推荐 5 本
- 《重构:改善既有代码的设计》第 2 版 - Martin Fowler:手法圣经
- 《修改代码的艺术》 - Michael Feathers:遗留代码急救
- 《测试驱动开发》 - Kent Beck:TDD 源头
- 《Effective Java》 - Joshua Bloch:Java 90 条守则
- 《Growing Object-Oriented Software, Guided by Tests》 - Freeman & Pryce:OO + TDD 结合
# 8.3 架构师推荐 5 本
- 《架构整洁之道》 - Robert C. Martin:Clean Architecture 全景
- 《实现领域驱动设计》 - Vaughn Vernon:DDD 落地
- 《构建微服务》第 2 版 - Sam Newman:微服务系统
- 《Software Engineering at Google》 - Titus Winters 等:Google 工程实践大成
- 《Accelerate》 - Nicole Forsgren 等:DevOps DORA 四大度量的科学证据
通读顺序建议:初级 5 本 → 高级 5 本 → 架构 5 本,每本读完做一次团队分享,用你自己的代码做案例。
# 8.4 一句话回顾
经典书目推荐路径,是本书之外的深度航线图——按身份分级,按需取阅。
# 8.5 核心要点
- 初级 5 本打地基
- 高级 5 本练心法
- 架构师 5 本立视野
# 8.6 带走清单
- [ ] 按身份选一份读书清单
- [ ] 每月至少读 1 本
- [ ] 读完写一份 1 页复盘
# 9. 专栏落幕
# 9.1 老陈最后周会
Day 117,14:00,代码医院会议室。
老陈把《代码医院手册》A4 打印稿摆在正中,环视一圈。小李、老王、小张、小周、小陆、沈总。
"各位,"老陈说,"90 天,我们做了一件事——把'代码越写越烂'这个无解问题,变成了一份可以复制的手册。"
"这本手册里没有魔法。它只有 108 条病案、18 种手法、90 条清单、12 条哲学。它不是终点,是起点——是你们下次面对新病人时的第一道防线。"
沈总接过手册,翻到最后一页,念出老陈手写的一句话:
"任何工具都会过时,只有'把代码当人来医'的心,永远不过时。"
会议室安静了 5 秒。然后掌声。
# 9.2 下一位接盘侠
老陈把手册合上,推到小李面前:
"小李,下一位接盘的不是你——是这本书的每一位读者。"
"因为我们花 90 天走过的路,他们能用 90 分钟读完。如果读完后,他们能少花 1 个月来救火——这本书就值了。"
小李接过手册,扉页上老陈写着:
致每一位读者:
代码不会自愈,但你可以。
—— 老陈 · Day 117
故事到此结束。
但每一位读到这里的读者——你的"Day 1",才刚刚开始。
# 9.3 一句话回顾
专栏落幕不是终点——它标记的是团队从'救火队'转向'免疫系统'的开始。
# 9.4 核心要点
- 老陈的最后一次周会是仪式,不是收官
- 下一位接盘侠会遇到新的病人
- 代码医院的文化必须能被传承
# 9.5 带走清单
- [ ] 把老陈的复盘话打印贴墙
- [ ] 为下一位接盘侠写一份 5 页交接
- [ ] 把'代码医院'文化写进团队 Wiki
# 10. 总速查表
# 10.1 一图看懂全专栏
《代码医院 · 品质工坊》14 篇总览
─────────────────────────────────
┌─────────────────────────────────┐
│ 科室 1 · 急诊科(01-06) │
│ 病例登记 → 命名 → 函数 → 边界 │
│ → 多态 → 遗留急救 │
├─────────────────────────────────┤
│ 科室 2 · 影像检验(07-09) │
│ 静态度量 → 覆盖真相 → 债量化 │
├─────────────────────────────────┤
│ 科室 3 · 外科与康复(10-12) │
│ 重构十八招 → 测试保命 → CR │
├─────────────────────────────────┤
│ 科室 4 · 预防医学(13) │
│ 新系统免疫力 │
├─────────────────────────────────┤
│ 附录 · 医生手册(14) │
│ 108 病案 · 18 手法 · 12 哲学 │
└─────────────────────────────────┘
# 10.2 按痛点反查手册
| 你的痛点 | 优先看 |
|---|---|
| 函数太长、参数太多 | 第 3 篇 F 系列 |
| 命名混乱 | 第 2 篇 N 系列 |
| 到处 try-catch 吞异常 | 第 4 篇 E 系列 |
| if-else 深嵌套 | 第 5 篇 C 系列 |
| 接手遗留系统不敢动 | 第 6 篇(Feathers 五步 SOP) |
| 覆盖率 80% 但 bug 依然多 | 第 8 篇 T01-T04 |
| 老板不给还债时间 | 第 9 篇(省/赚/避三话术) |
| 团队 lgtm 严重 | 第 12 篇 R01 |
| 新项目怕重蹈覆辙 | 第 13 篇(免疫力五层) |
| 想要总目录 | 本篇(第 14 篇) |
# 10.3 送给读者的一封信
亲爱的读者:
如果你从头读到这里,谢谢你陪老陈走完这 90 天。
这本书讲的从来不是"如何写完美代码"——因为完美不存在。它讲的是:
如何在不完美的现实里,一天比一天更好。
也许你团队里也有一个"OrderMonolith",也许你就是那个"小李",也许你正在被"lgtm 文化"折磨,也许你即将开启一个新项目。
不管你在哪一天——Day 1 也好,Day 90 也好,都记得:
代码是写给未来的人读的, 那个人可能是同事, 也可能是三个月后的你自己。 请对未来的你,好一点。祝你的代码一天比一天更清晰, 祝你的团队一天比一天更专业, 祝你在下一次事故复盘时,能骄傲地说:
"这次,我们提前拦住了。"
——杨充 · 代码医院终章
# 10.4 全文快速回顾
- 第 1 章:手册序言 · 90 天诊疗回顾
- 第 2 章:108 条病案编号全表(N/F/C/E/T/A/D/R)
- 第 3 章:18 招手法索引
- 第 4 章:三视角带走清单汇总
- 第 5 章:90 天诊疗完整时间轴
- 第 6 章:度量对照大表
- 第 7 章:12 大设计哲学
- 第 8 章:经典书目推荐路径
- 第 9 章:专栏落幕 · 老陈的最后一次周会
# 10.5 核心要点串联
- 索引即资产:可检索的知识才是团队资产
- 哲学即心法:12 条短句托住 14 篇内容
- 时间轴即节奏:90 天证明重构是工程
- 度量即证据:曲线比感觉更能说服人
- 传承即文化:接盘侠也能沿用这本手册
# 10.6 常见误区汇总
- ❌ 只读文章,不建立自己的索引
- ❌ 只学手法,不理解设计哲学
- ❌ 只看单点数字,不建立度量曲线
- ❌ 只关注自己身份的清单,不了解上下层
- ❌ 把手册当摆设,不进入日常工作流
# 10.7 带走清单总表
- [ ] 108 条病案编号贴到 CR 模板
- [ ] 18 招手法按分类每周练习
- [ ] 三视角清单按身份挑选执行
- [ ] 三张度量曲线纳入研发看板
- [ ] 12 大哲学打印贴工位
《代码品质工坊 · 代码医院》14 篇 · 全篇终