编程进阶网 编程进阶网
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机的原理
  • 操作系统原理
  • 网络协议原理
  • 数据库的原理
  • 序卷导读
  • 数据本质
  • 运行模型
  • 并发设计
  • 内存真相
  • 交互系统
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 技能之旅
  • 体系建设
  • 代码品质
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 性能优化
  • 数据结构导论
  • 线性结构详解
  • 树哈希结构论
  • 容器设计实战
  • 经典算法思想
  • 工程案例剖析
  • 算法题库精练
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript案例
  • JavaScript高级
  • Kotlin精通
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 毛选解读
  • 自我精进
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 在线工具
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 加解密
  • 时间日期
  • 网络工具
  • 颜色设计
  • 二维码
  • 开发实用
  • 计算机的原理
  • 操作系统原理
  • 网络协议原理
  • 数据库的原理
  • 序卷导读
  • 数据本质
  • 运行模型
  • 并发设计
  • 内存真相
  • 交互系统
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 技能之旅
  • 体系建设
  • 代码品质
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 性能优化
  • 数据结构导论
  • 线性结构详解
  • 树哈希结构论
  • 容器设计实战
  • 经典算法思想
  • 工程案例剖析
  • 算法题库精练
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++编程技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript案例
  • JavaScript高级
  • Kotlin精通
  • Android库解读
  • Android专栏
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • 毛选解读
  • 自我精进
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • 体系建设优化

  • 代码品质工坊

    • README
    • 01.代码医院开院首诊
    • 02.命名与意图的战场
    • 03.函数与职责大手术
    • 04.错误与边界的防线
    • 05.条件与多态心律术
    • 06.遗留代码急救手册
    • 07.静态分析度量诊断
    • 08.测试覆盖率的真相
    • 09.技术债量化与还款
    • 10.重构十八招式详解
    • 11.测试保命术全解析
    • 12.代码审查文化建设
    • 13.新系统免疫力建设
      • 1. 急诊病例
        • 1.1 新项目亦生病
        • 1.2 首周现坏味
        • 1.3 本篇待答疑问
        • 1.4 一句话回顾
        • 1.5 核心要点
        • 1.6 带走清单
      • 2. 病理诊断
        • 2.1 六大早发病
        • 2.2 A 系列病案登记
        • 2.3 一句话回顾
        • 2.4 核心要点
        • 2.5 带走清单
      • 3. 病因追溯
        • 3.1 从零为何烂
        • 3.2 免疫缺失症状
        • 3.3 一句话回顾
        • 3.4 核心要点
        • 3.5 带走清单
      • 4. 治疗方案总纲
        • 4.1 免疫力五层护栏
        • 4.2 分层与契约
        • 4.3 一句话回顾
        • 4.4 核心要点
        • 4.5 带走清单
      • 5. 住院医查房
        • 5.1 首周四件事
        • 5.2 PR 工单模板
        • 5.3 初级带走清单
      • 6. 主治查房
        • 6.1 API 契约设计
        • 6.2 领域模型 + 防腐层
        • 6.3 高级带走清单
      • 7. 主任查房
        • 7.1 品质预算与 SLO
        • 7.2 组织免疫建设
        • 7.3 架构师带走清单
      • 8. 术后康复曲线
        • 8.1 首月度量对照
        • 8.2 老系统早期对比
        • 8.3 一句话回顾
        • 8.4 核心要点
        • 8.5 带走清单
      • 9. 病案归档
        • 9.1 A 系列编号
        • 9.2 全专栏连接
        • 9.3 一句话回顾
        • 9.4 核心要点
        • 9.5 带走清单
      • 10. 综合案例串讲
        • 10.1 病例真相揭晓
        • 10.2 新服务首月轴
        • 10.3 设计哲学回扣
        • 10.4 速查一图
        • 10.5 全文快速回顾
        • 10.6 核心要点串联
        • 10.7 常见误区汇总
        • 10.8 带走清单总表
    • 14.医生手册总结索引
    • 写作模板
  • 稳定性与可靠性

  • 工程化与运维

  • 方案设计思想

  • 性能优化实践

  • 真经
  • 代码品质工坊
杨充
2026-06-27
目录

13.新系统免疫力建设

# 13.新系统免疫力建设

本篇定位:外科第四篇 · 预防医学——Greenfield 项目如何从 0 建立品质免疫力。

剧情节点:Day 86-90——OrderMonolith 交给小李接管。老陈立刻转向公司启动的新业务「次日达」,团队问:"这次能不能不生病?"预防医学开讲。

本篇病人:P-005 NextDaySvc 次日达新系统 · 从 0 搭建时如何守住品质。

承接经典:Robert C. Martin《架构整洁之道》/ Vaughn Vernon《实现领域驱动设计》/ Sam Newman《构建微服务》/ Google《Software Engineering at Google》第 3 部分。

本篇病案编号范围:A11-A15(架构类收尾) + 全系列预防性检查项


# 目录介绍

  • 1. 急诊病例
    • 1.1 新项目亦生病
    • 1.2 首周现坏味
    • 1.3 本篇待答疑问
    • 1.4 一句话回顾
    • 1.5 核心要点
    • 1.6 带走清单
  • 2. 病理诊断
    • 2.1 六大早发病
    • 2.2 A 系列病案登记
    • 2.3 一句话回顾
    • 2.4 核心要点
    • 2.5 带走清单
  • 3. 病因追溯
    • 3.1 从零为何烂
    • 3.2 免疫缺失症状
    • 3.3 一句话回顾
    • 3.4 核心要点
    • 3.5 带走清单
  • 4. 治疗方案总纲
    • 4.1 免疫力五层护栏
    • 4.2 分层与契约
    • 4.3 一句话回顾
    • 4.4 核心要点
    • 4.5 带走清单
  • 5. 住院医查房
    • 5.1 首周四件事
    • 5.2 PR 工单模板
    • 5.3 初级带走清单
  • 6. 主治查房
    • 6.1 API 契约设计
    • 6.2 领域模型 + 防腐层
    • 6.3 高级带走清单
  • 7. 主任查房
    • 7.1 品质预算与 SLO
    • 7.2 组织免疫建设
    • 7.3 架构师带走清单
  • 8. 术后康复曲线
    • 8.1 首月度量对照
    • 8.2 老系统早期对比
    • 8.3 一句话回顾
    • 8.4 核心要点
    • 8.5 带走清单
  • 9. 病案归档
    • 9.1 A 系列编号
    • 9.2 全专栏连接
    • 9.3 一句话回顾
    • 9.4 核心要点
    • 9.5 带走清单
  • 10. 综合案例串讲
    • 10.1 病例真相揭晓
    • 10.2 新服务首月轴
    • 10.3 设计哲学回扣
    • 10.4 速查一图
    • 10.5 全文快速回顾
    • 10.6 核心要点串联
    • 10.7 常见误区汇总
    • 10.8 带走清单总表

# 1. 急诊病例

# 1.1 新项目亦生病

Day 86,OrderMonolith 完成"90 天疗程"最后一次交接,小李正式接管。老陈端着新买的咖啡,被沈总在电梯口拦住:

"老陈,公司新业务'次日达(NextDaySvc)'正式立项,团队 6 人,你带。要求 8 周内 MVP 上线——但这一次,不能再走 OrderMonolith 的老路。"

老陈一口咖啡卡在喉咙里。他清楚知道:新项目最容易犯的错,就是重蹈旧项目所有的错——因为团队普遍相信"新代码总是干净的"。

老陈请出了他从 OrderMonolith 事故中学到的一句话:

"代码腐化不是老代码的专利——它从 Day 1 就在潜伏。"

Day 86 立项会上,团队 5 人(老王资深、小李轮岗、小张恢复、加两位新招工程师小周与小陆)签订了一份"品质公约",作为项目文化基石。

# 1.2 首周现坏味

老陈警惕地在 Day 91(正式开发第 5 天)做了一次预防性静态扫描,结果令人震惊:

度量项 Day 91(新项目 5 天) OrderMonolith 早期(Day 5,历史回溯) 判定
圈复杂度 max 8 5 已经在上升
God Class(>500 行) 1 个 OrderFacade 已达 340 行 0 预警
循环依赖 0 0 暂安全
未 mock 的 IO 单测 2 个 0 已经在腐化
DTO 与 Domain 边界 未分层,直接透传 已分层(早期) 重症
是否有 ADR 无 无 传统病

老陈心里凉了半截:5 天,坏味道已经开始。新项目并不天然干净,它只是"病还没被发现"。

沈总在这次预扫描会议上敲桌:

"我们之前是给病人治病——现在要给健康人打疫苗。这就是本篇要解决的问题。"

# 1.3 本篇待答疑问

老陈在白板中央写下 5 个问号:

  1. 为什么新项目 5 天就有坏味道? 是能力问题还是习惯问题?
  2. 免疫力有哪些具体成分? 具体拆成哪些技术护栏?
  3. 哪些事必须在第 1 周做完,哪些可以推迟? 有没有节奏表?
  4. 架构师如何用"品质预算"约束未来 30 天? 预算怎么定?
  5. 组织层面如何让"预防医学"变成招聘、培训、传承的默认?

这 5 个问号将贯穿本篇。

"下集提要(本节):先看病理——新系统的六大早发病。你会发现它们和 OrderMonolith 90 天前遇到的是同一批病。"

# 1.4 一句话回顾

新项目也难逃生病——第 5 天就出现的坏味道,是免疫力建设最好的开场白。

# 1.5 核心要点

  • Greenfield 不等于健康
  • 坏味道从第 1 周就开始积累
  • 免疫力必须从 Day 1 建立

# 1.6 带走清单

  • [ ] Day 1 建立最小护栏
  • [ ] Day 5 前完成 CI + 门禁
  • [ ] Day 30 出第一次健康度报告

# 2. 病理诊断

# 2.1 六大早发病

老陈总结出新系统前 30 天最常出现的六大早发病(E1-E6):

编号 名称 典型症状 埋雷时间
E1 无边界大类 Facade / Service 一开始就承担 3+ 职责 第 1-3 天
E2 透传 DTO HTTP DTO 直入 Repository 或跨模块传递 第 3-7 天
E3 无 ADR 决策 大决策口头达成,1 个月后没人记得为什么 第 5-10 天
E4 假测试 测试全部 mock、无实际断言 第 5-10 天
E5 配置蔓延 环境变量/开关到处散落,无统一 config schema 第 10-15 天
E6 观测缺失 无 metrics、无 traceId、无结构化日志 第 15-30 天

这六大病都符合三个特征:

  • 潜伏期长:几周内不会崩,等到 3 个月后已成积重
  • 修复成本指数上升:Day 5 修一次是 1 小时,Day 90 修同样问题是 1 周
  • 具备"传染性":一个人破例就会有第二个人跟进

老陈画了一张"Boehm 缺陷成本曲线"(来自 Barry Boehm 经典研究):

修复成本
  ▲
  │
  │                                    ● 生产 (100x)
  │
  │                          ● UAT (25x)
  │
  │              ● 系统测试 (10x)
  │
  │       ● 单测阶段 (3x)
  │
  │● 编码阶段 (1x)
  └──────────────────────────────────────▶ 时间

结论:免疫力 = 让缺陷停在 1x 阶段。

# 2.2 A 系列病案登记

病案卡 A11:无边界大类(Big Ball of Mud 苗头)

  • 症状:OrderFacade 340 行、Day 5 已复用于 3 个场景
  • 危险等级:★★★★★(会长成 P-001)
  • 首次出现:NextDaySvc Day 5
  • 影响:3 个月后必然进入 P-001 状态
  • 治疗手段:分层架构 + 单类 300 行硬约束 + Sonar 门禁

病案卡 A12:DTO 透传

  • 症状:CreateOrderRequest 从 Controller 一路传到 Repository
  • 危险等级:★★★★☆
  • 首次出现:NextDaySvc Day 5
  • 影响:改一个字段影响整个链路
  • 治疗手段:分层 DTO(HTTP DTO / Command / Domain / Entity)+ 转换器

病案卡 A13:无 ADR

  • 症状:为什么选择 PostgreSQL 而不是 MySQL?无人能说清
  • 危险等级:★★★☆☆
  • 首次出现:NextDaySvc Day 6
  • 影响:一年后决策无法审计
  • 治疗手段:ADR (Architecture Decision Records) 模板 + Git 归档

病案卡 A14:观测缺失

  • 症状:无 traceId、无 metric、无结构化日志
  • 危险等级:★★★★★
  • 首次出现:NextDaySvc Day 10
  • 影响:上线后事故无法定位
  • 治疗手段:第 1 周就接入 OpenTelemetry + 日志规范

病案卡 A15:假测试(承接 A03/A04 A11)

  • 症状:测试全 mock、只测 mock、无真实断言
  • 危险等级:★★★★☆
  • 首次出现:NextDaySvc Day 5
  • 影响:等到集成阶段才发现 bug
  • 治疗手段:Test 金字塔占比强制 + Testcontainers 集成 + 变异测试

# 2.3 一句话回顾

新系统的六大早发病 + A11-A15 病案编号,是新项目最容易踩的坑。

# 2.4 核心要点

  • 架构病比代码病更贵
  • 早发病往往由团队习惯带来
  • 编号让新项目也能沉淀经验

# 2.5 带走清单

  • [ ] A11-A15 表贴到项目 wiki
  • [ ] 架构评审必查六大早发病
  • [ ] 新项目 Day 30 复盘早发病

# 3. 病因追溯

# 3.1 从零为何烂

Day 91 复盘会上,老陈问团队:"我们都从事故中活过来了,为什么 5 天又开始烂?"团队回答:

  • 小李:"我以为新项目可以'快点写',规矩后面再补。"
  • 老王:"业务方催得急,MVP 优先。"
  • 小张:"我不知道要不要一开始就分层——教科书说 YAGNI。"
  • 小周(新人):"我按前公司的习惯写的,那边就是 Controller 直接调 Repo。"

老陈把这四种心态归纳为新系统免疫失败四大心理根因:

根因 心态 破解方向
N-Speed(速度诱惑) "先跑起来再说" 预设速度上限 + 品质预算
N-Pressure(业务压力) "MVP 优先" MVP 定义包含品质
N-YAGNI(过度援引) "分层就是过度设计" 区分结构必要 vs 提前抽象
N-Habit(旧习惯) "以前一直这样写" 入职品质培训 + 结对编程

关键洞察:新项目并不会天然干净——它只是"病还没长出来"。免疫力必须从 Day 1 建立,因为Day 30 之后再补,成本已经是 10 倍。

# 3.2 免疫缺失症状

老陈用一个更形象的比喻:新系统的免疫缺失,就像不打疫苗的孩子。

症状 1:无抗体(Test/Contract 缺失)

  • 没有测试守门 → 一改就出问题
  • 没有 API 契约 → 上下游一动就崩

症状 2:无免疫记忆(ADR/Runbook 缺失)

  • 没有决策记录 → 3 个月后无人知道为何这样设计
  • 没有事故本 → 同样的错犯第二次

症状 3:无免疫细胞识别(分层/边界缺失)

  • 没有分层 → 病灶迅速扩散
  • 没有边界 → 一个模块的问题传染全系统

三大症状对应三个护栏:

  • 抗体 → 测试 + 契约
  • 记忆 → ADR + Runbook + Postmortem
  • 识别 → 分层架构 + 防腐层

**"下集提要(本节):**病因清楚。下一节看治疗方案——免疫力五层护栏。"

# 3.3 一句话回顾

从 0 开始也依然会烂——因为免疫缺失的三大症状,与团队习惯高度相关。

# 3.4 核心要点

  • 坏习惯会被搬进新项目
  • 流程缺失是免疫缺失的第一信号
  • 文化决定新项目的健康上限

# 3.5 带走清单

  • [ ] 新项目 Day 1 就要有 CR 卡点
  • [ ] 盘一下团队坏习惯清单
  • [ ] 把文化红线写入项目 README

# 4. 治疗方案总纲

# 4.1 免疫力五层护栏

老陈画了一张"免疫力五层护栏"图,作为新系统 Day 1 的架构宪法:

┌─────────────────────────────────────────────────┐
│ Layer 5: 组织(招聘 · 培训 · 品质预算 · SLO)   │
├─────────────────────────────────────────────────┤
│ Layer 4: 运行(观测 · 混沌工程 · 灰度 · 回滚)  │
├─────────────────────────────────────────────────┤
│ Layer 3: 交付(CI 门禁 · 契约测试 · Preview)   │
├─────────────────────────────────────────────────┤
│ Layer 2: 代码(分层架构 · 防腐层 · 契约测试)   │
├─────────────────────────────────────────────────┤
│ Layer 1: 决策(ADR · MVP 定义 · 品质预算)      │
└─────────────────────────────────────────────────┘

五层协同才能建立真正的免疫力。一个新项目在 Day 1 就应完成这五层的"疫苗接种"。

# 4.2 分层与契约

核心分层参考 Clean Architecture(Robert C. Martin):

外部
┌────────────────────────────────┐
│   Adapters(Controller/Kafka) │  ← HTTP DTO 只活在这层
├────────────────────────────────┤
│   Application(Use Cases)     │  ← Command / Query
├────────────────────────────────┤
│   Domain(Entity + Value)     │  ← 业务规则的家
├────────────────────────────────┤
│   Infrastructure(Repo/HTTP)  │  ← 通过接口反向依赖
└────────────────────────────────┘

依赖方向铁律:外层依赖内层,内层永远不知道外层存在。

以 NextDaySvc 为例:

// ✅ 正确:Domain 定义接口
package com.nds.domain;

public interface OrderRepository {
    Optional<Order> findById(OrderId id);
    void save(Order order);
}

// Infrastructure 实现接口
package com.nds.infra.jpa;

@Repository
public class JpaOrderRepository implements OrderRepository {
    // JPA 细节仅存在这里
}

分层 DTO 规范(对齐 A12):

层 DTO 类型 目的 命名
Adapter CreateOrderHttpRequest HTTP 边界 *HttpRequest/Response
Application CreateOrderCommand 用例入参 *Command / *Query
Domain Order (Aggregate) 业务实体 纯业务名
Infrastructure OrderEntity 存储映射 *Entity

层间转换用 Mapper(MapStruct):

@Mapper
public interface OrderMapper {
    CreateOrderCommand toCommand(CreateOrderHttpRequest req);
    OrderEntity      toEntity(Order order);
    Order            fromEntity(OrderEntity entity);
}

关键效果:改 HTTP DTO 字段,Repository 不受任何影响。

**"下集提要(本节):**总纲清楚。下一节住院医查房——新项目第 1 周就要建的 4 件事。"

# 4.3 一句话回顾

免疫力五层护栏 + 分层架构与接口契约,是新项目可复现的健康骨架。

# 4.4 核心要点

  • 五层护栏覆盖代码 → 架构 → 契约 → 流程 → 文化
  • 分层不清晰是所有腐化的起点
  • 契约是模块之间的免疫屏障

# 4.5 带走清单

  • [ ] 项目 Day 1 就定义分层与依赖方向
  • [ ] 接口契约先行,实现在后
  • [ ] 每层护栏都要有对应度量

# 5. 住院医查房

# 5.1 首周四件事

目标读者:新加入项目的初中级开发(小周、小陆),需要知道"入手就该做什么"。

四件事一览:

序号 事项 交付物 期限
1 代码脚手架 + 分层骨架 空 Controller/UseCase/Domain/Infra 各 1 个类 Day 1-2
2 CI 门禁 + 测试脚手架 GitHub Actions + Jacoco + Testcontainers Day 2-3
3 PR/Issue/ADR 模板 .github/ 目录三个模板 Day 3
4 观测最小闭环 结构化日志 + traceId + 一个 hello metric Day 3-5

这四件事的哲学:先把"跑不通品质门禁"变成"痛苦",让后续每一行代码天然被约束。

详细展开每一件事:

# 事项 1:分层骨架

com.nds/
  adapter/
    http/OrderController.java
  application/
    CreateOrderUseCase.java
  domain/
    order/Order.java
    order/OrderRepository.java   ← 接口
  infrastructure/
    persistence/JpaOrderRepository.java  ← 实现

Day 1 就有 4 层,即使功能只有一个 hello world。

# 事项 2:CI 门禁

name: NDS PR Gate
on: [pull_request]
jobs:
  quality-gate:
    steps:
      - uses: actions/checkout@v4
      - name: Build & Test
        run: ./gradlew build jacocoTestReport
      - name: Coverage Gate
        run: |
          coverage=$(cat build/reports/coverage.txt)
          if (( $(echo "$coverage < 80" | bc -l) )); then
            echo "Coverage below 80%"; exit 1
          fi
      - name: Sonar (Clean as You Code)
        run: ./gradlew sonar
      - name: PIT Mutation Score
        run: ./gradlew pitest
      - name: PR Size Check
        run: |
          lines=$(git diff --numstat origin/main HEAD | awk '{sum+=$1} END {print sum}')
          if [ $lines -gt 400 ]; then echo "PR too large"; exit 1; fi

# 事项 3:三大模板

PR 模板(.github/PULL_REQUEST_TEMPLATE.md):

### Why
### How
### Testing
### Risk
### Rollback

ADR 模板(docs/adr/000-template.md):

# ADR-XXX: [标题]
- Status: proposed / accepted / superseded
- Date: YYYY-MM-DD
- Author: @xxx

## Context
## Decision
## Alternatives Considered
## Consequences

Issue 模板:Bug / Feature / Chore 各一份。

# 事项 4:观测最小闭环

// 结构化日志 + traceId 自动注入
@Slf4j
@RestController
public class OrderController {
    private final Counter orderCreatedCounter = Metrics.counter("nds.order.created");
    
    @PostMapping("/orders")
    public ResponseEntity<?> create(@RequestBody CreateOrderHttpRequest req) {
        log.info("order.create.received orderKey={}", req.orderKey());
        // ... 业务
        orderCreatedCounter.increment();
        return ResponseEntity.ok(...);
    }
}

Day 5 交付验证:

  • ☐ 空业务但 CI 通过
  • ☐ Sonar 首次扫描:0 issue、覆盖率 100%(因为没代码)
  • ☐ Grafana 上能看到 nds.order.created metric

# 5.2 PR 工单模板

关键原则:模板存在的意义是降低"该写什么"的心理负担。

PR 模板延伸字段(比第 12 篇更细):

### Why
问题背景与业务价值(1-3 句)

### How
- 涉及模块与关键改动点
- 关键类/方法

### Testing
- [ ] 单测新增/更新
- [ ] 集成测试
- [ ] 手工验证步骤

### Risk
- 破坏性变更:无 / 有(详述)
- 兼容性:向前兼容 / 需迁移

### Rollback
- 回滚方式:Git revert / 灰度关闭 / DB migration down

### Related
- Issue: #xxx
- ADR: adr/xxx.md

Issue 模板 - Bug:

### 环境
- 版本:
- 环境:dev / uat / prod
- 影响用户:

### 复现步骤
1.
2.

### 期望 / 实际
### 附件(日志/截图/traceId)

# 5.3 初级带走清单

  • ☐ 入职 Day 1 先建 4 层目录
  • ☐ CI 门禁不通过决不合并
  • ☐ 每个 PR 用模板四段
  • ☐ 每个 API 有 traceId
  • ☐ 每个决策超过 30 分钟争论 → 写 ADR
  • ☐ 分不清 DTO 层级 → 问老陈或看第 6 章

# 6. 主治查房

# 6.1 API 契约设计

目标读者:老王等资深工程师,需要为团队定接口设计规则。

API 契约五条硬规则:

规则 1:向后兼容优先

  • 只加字段,不改字段类型
  • 删字段 → 走 6 个月弃用期(Deprecated 标记 + 双写 + 告警)

规则 2:显式版本

/v1/orders
/v2/orders   # 破坏性变更时新增

规则 3:Idempotency-Key(幂等键)

POST /v1/orders
Idempotency-Key: 4f89a-...

规则 4:错误码规范

{
  "code": "NDS.ORDER.OUT_OF_STOCK",
  "message": "Item xyz is out of stock",
  "traceId": "abc-123"
}

规则 5:OpenAPI 契约

  • 用 OpenAPI 3.0 定义
  • 用 Prism 起 mock server 提前给上下游
  • 用 Pact 做消费者驱动契约测试(对齐第 11 篇 T10)

跨语言对比:接口契约实现

语言 主流工具 关键点
Java springdoc + Pact JVM 从代码生成 OpenAPI + 契约验证
Go swag + Pact Go 注释生成 spec + Pact 消费者
Python FastAPI + schemathesis 自动生成 spec + fuzz testing
TypeScript tRPC / zod + Pact Node 类型即契约

# 6.2 领域模型 + 防腐层

Vaughn Vernon 在《实现领域驱动设计》里说:

"Anti-Corruption Layer 是保护你的领域不被别人污染的最后一道墙。"

NextDaySvc 案例:与老 OrderMonolith 集成

问题:新系统需要读取 OrderMonolith 的 order 数据,但对方数据结构混乱。

错误方案:直接把 OrderMonolith 的 DTO 拉进来用。

正确方案(防腐层):

// domain/order/Order.java —— 我们自己的干净模型
public class Order {
    private OrderId id;
    private Customer customer;
    private Money total;
    private OrderStatus status;
    // ...
}

// infrastructure/adapter/legacy/OrderMonolithClient.java
@Component
public class OrderMonolithClient {
    // 调用 legacy API 拿"脏"数据
    LegacyOrderDto fetchLegacy(String id);
}

// infrastructure/adapter/legacy/LegacyOrderTranslator.java
@Component
public class LegacyOrderTranslator {
    // ⭐ 防腐层:翻译 legacy DTO → 我们的 Domain
    public Order translate(LegacyOrderDto legacy) {
        return Order.builder()
            .id(new OrderId(legacy.getOid()))
            .customer(new Customer(legacy.getUname()))
            .total(Money.of(legacy.getAmt() / 100, "CNY"))  // 分转元
            .status(mapStatus(legacy.getSt()))
            .build();
    }
}

规则:Legacy 世界的一切"脏"永远不能穿过防腐层进入 Domain。

# 6.3 高级带走清单

  • ☐ API 五条契约硬规则从 Day 1 生效
  • ☐ 用 OpenAPI 3.0 定义 + Prism mock + Pact 契约
  • ☐ 与遗留系统集成 → 强制防腐层
  • ☐ 领域模型不含技术细节(JPA/HTTP/Kafka)
  • ☐ Domain 定义接口,Infrastructure 实现
  • ☐ 每季度回扫依赖方向:是否有内层引用外层?

# 7. 主任查房

# 7.1 品质预算与 SLO

目标读者:沈总这类架构师/PM,需要用组织层机制约束品质。

"品质预算(Quality Budget)" 概念来自 Google SRE:允许一定的不完美,但设定不可越界的上限。

NextDaySvc 品质预算示例:

维度 上限 触发动作
生产事故率 每月 ≤ 2 起 P2+ 超限 → 冻结新需求 1 周
服务可用性 SLO ≥ 99.9%/月 消耗 error budget 后停发布
单测覆盖率 增量 ≥ 80% Sonar 门禁自动拦
PIT 变异分数 增量 ≥ 0.7 CI 自动拦
技术债比 ≤ 5% 每冲刺预留 20% 时间还债
PR lgtm 率 ≤ 15% 周会 CR 高光
事故 MTTR ≤ 30min 观测 + Runbook

品质预算的政治价值:当业务方催速度时,架构师可以指着预算说 "现在越界,将来必崩"。

沈总把这份预算做成一张仪表盘,钉在办公室:

NextDaySvc · Quality Dashboard      Day 91 / 8 周
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
可用性 SLO       99.98%   ████████████████░  预算余额 84%
覆盖率(增量)     82.4%    █████████████████  ≥80 ✅
变异分数         0.74     ████████████████░  ≥0.7 ✅
技术债比         2.1%     ██████████████░░░  <5 ✅
LGTM 率(周)      11%      █████████████████  <15 ✅
生产事故(30d)    0/2      █████████████████  预算余额 100%
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
状态:✅ 所有指标在预算内

# 7.2 组织免疫建设

免疫力必须组织化,否则一个人一走,团队又回到原点。三大机制:

机制 1:招聘筛品质基因

  • 面试第 3 轮加"代码审查题":给应聘者一段真实历史 PR,让他 CR 30 分钟
  • 观察三点:是否分级意见(nit/consider/must)、是否给方案、是否礼貌
  • 结果 → 判断其"品质文化契合度"

机制 2:入职 30 天品质训练营

周次 内容 交付物
Week 1 分层架构 + 防腐层 + 团队 Style Guide 通过基础测验
Week 2 测试金字塔 + Testcontainers + PIT 独立写完 1 个 UseCase 全套测试
Week 3 CR 卡点 + 60 条清单 + 三句式 结对完成 3 次 PR
Week 4 观测 + Runbook + 事故复盘 参与 1 次故障复盘

机制 3:传承 —— 三个仪式

  1. 每月 ADR Review:全员回顾本月新决策
  2. 每季度 Postmortem 讲堂:过去 3 个月事故一次讲透
  3. 年度品质工坊:邀请外部专家 + 内部经验分享

关键洞察:技术护栏可以复制,品质文化只能培养。招聘、培训、传承是唯一路径。

# 7.3 架构师带走清单

  • ☐ Day 1 就定品质预算 + SLO
  • ☐ 每周仪表盘 → 品质状态可见
  • ☐ 面试筛品质基因(不只筛技术)
  • ☐ 30 天新人训练营 = 组织的疫苗
  • ☐ ADR Review / Postmortem 讲堂 / 品质工坊 三仪式
  • ☐ 每季度回顾"预算是否被消耗、为什么"

# 8. 术后康复曲线

# 8.1 首月度量对照

NextDaySvc Day 86-Day 116(30 天),关键指标:

度量项 Day 91(第 5 天预警) Day 116(30 天后) 目标水位 判定
圈复杂度 max 8 6 ≤ 10 ✅
单类 max 行数 340 185 ≤ 300 ✅
循环依赖 0 0 0 ✅
未 mock 的 IO 单测 2 0 0 ✅
覆盖率(增量) 62% 83% ≥ 80% ✅
PIT 变异分数 0.48 0.76 ≥ 0.7 ✅
ADR 数量 0 11 ≥ 8 ✅
Sonar 阻断 issue 6 0 0 ✅
lgtm-only PR 率 未监控 9.2% ≤ 15% ✅
生产事故(30d) — 0 ≤ 2 ✅

沈总在 Day 116 复盘会上说:

"30 天,0 事故,全预算未消耗——这就是免疫力。它不是没病,是把病挡在了 Day 5。"

# 8.2 老系统早期对比

老陈做了一张"两个项目同期指标对比":

指标 NextDaySvc Day 30 OrderMonolith 历史 Day 30
圈复杂度 max 6 14
单类 max 行数 185 690
循环依赖 0 4
覆盖率 83% 24%
生产事故(30d) 0 3
ADR 11 0
CR 通过 lgtm 率 9.2% 无度量

"这就是打疫苗和不打的差别。" 老陈把这两列对比投在大屏上,会议室鸦雀无声。

# 8.3 一句话回顾

30 天后与 OrderMonolith 早期的对比,是新项目免疫力建设投入产出比的直接证据。

# 8.4 核心要点

  • 新项目 30 天的健康度可以量化
  • 免疫力建设越早越省
  • 早期投入 1,后期节省 10

# 8.5 带走清单

  • [ ] Day 30 出健康度报表
  • [ ] 与团队历史项目做基线对比
  • [ ] 把健康度纳入季度指标

# 9. 病案归档

# 9.1 A 系列编号

编号 名称 关键指标 治疗手段
A11 无边界大类 单类 > 300 行 分层 + 单类硬约束 + Sonar
A12 DTO 透传 HTTP DTO 穿透层 分层 DTO + MapStruct 转换
A13 无 ADR 决策无记录 ADR 模板 + Git 归档
A14 观测缺失 无 traceId/metric Day 1 观测闭环
A15 假测试 Mock 无断言 金字塔占比 + PIT + Testcontainers

# 9.2 全专栏连接

  • N01-N05(命名类):Day 1 就通过 Style Guide 预防
  • F01-F05(函数类):Day 1 Sonar Cognitive 门禁预防
  • C01-C05(条件类):Day 1 分层 + 策略模式预防
  • E01-E05(错误边界):Day 1 契约五规则预防
  • T01-T12(测试类):Day 1 CI 门禁 + PIT 强制
  • D01-D10(度量/债务类):Day 1 品质预算预防
  • R01-R08(CR 类):Day 1 三层门禁自动执行

病案总览统计(截至本篇):全专栏共登记 62 个病案(N×5 + F×5 + C×5 + E×5 + T×12 + A×15 + D×10 + R×8 - 部分复用编号),构成完整的《代码疾病 ICD 手册》。

# 9.3 一句话回顾

A11-A15 病案 + 全专栏连接,就是新项目免疫力建设的最小执行合集。

# 9.4 核心要点

  • 新项目也需要病案编号
  • 编号让新项目沉淀成团队资产
  • 归档是团队免疫力的复利

# 9.5 带走清单

  • [ ] A11-A15 表进 CR 模板
  • [ ] 新项目 Day 30 补充新编号
  • [ ] 把编号命中率纳入季度指标

# 10. 综合案例串讲

# 10.1 病例真相揭晓

NextDaySvc 8 周 MVP 上线全流程真相:

  • Day 86-90:项目启动 → 品质公约签订 + 五层护栏铺设
  • Day 91:预防性静态扫描发现 5 大坏味道 → 立即修正
  • Day 92-100:分层架构 + 防腐层落地 → 与 OrderMonolith 联调
  • Day 101-115:核心业务 UseCase 开发 + 契约测试 + 变异测试
  • Day 116:30 天中期健康检查 → 全部指标在预算内
  • Day 130(预计):8 周 MVP 上线 → 打赌不会有 P1 事故

Day 116 的中期报告扉页写着:

"这不是新系统会不会生病的赌注——这是新系统能不能拒绝生病的证明。"

# 10.2 新服务首月轴

Day 86(周一)· 立项

  • 品质公约签订 · 团队成员宣誓
  • 5 层护栏方案通过
  • 品质预算与 SLO 确定

Day 87(周二)· 脚手架 Day 1

  • 4 层目录建立
  • CI 门禁 v1 部署
  • 观测最小闭环上线(Grafana 显示第 1 个 metric)

Day 88-90(周三-周五)· 脚手架完善

  • PR/Issue/ADR 三模板启用
  • OpenAPI 契约首版发布
  • Testcontainers 集成

Day 91(周一)· 首次预防扫描

  • 发现 A11-A15 五大坏味道
  • 立即整改,Day 92 全部关闭

Day 92-100(第 2 周)· 与 legacy 集成

  • 防腐层落地
  • Pact 契约测试首个用例
  • ADR-003(为何用 PostgreSQL 而非 MySQL)归档

Day 101-115(第 3-5 周)· 核心业务开发

  • 5 个 UseCase 交付
  • 变异测试分数稳定 ≥ 0.7
  • 组织级:新人 2 周训练营首期开营

Day 116(第 6 周初)· 中期检查

  • 品质仪表盘全绿
  • 团队第一次感到"这项目跟以前不一样"

# 10.3 设计哲学回扣

Robert C. Martin 在《架构整洁之道》里说:

"The goal of software architecture is to minimize the human resources required to build and maintain the required system."(软件架构的目标是最小化构建与维护系统所需的人力。)

Vaughn Vernon 在《DDD》里说:

"Strategic design is where the value lives; tactical patterns are just tools."(战略设计才是价值所在;战术模式只是工具。)

Sam Newman 在《构建微服务》里说:

"A service that's not observable is a black box—it will fail in ways you cannot debug."

这三句话共同指向一件事:免疫力不是技术手段的堆砌,是决策与文化的沉淀。

"新系统免疫力"的核心哲学(老陈总结):

"最强的品质工程,不是治病救人,而是从 Day 1 让病无处可长。"

回顾整个专栏,我们可以画出一条完整的进化路径:

Day 1  → 病案登记(第 1-5 篇:单点疾病)
Day 30 → 遗留急救(第 6 篇:症状缓解)
Day 60 → 静态度量 + 覆盖真相(第 7-8 篇:影像检验)
Day 70 → 债务量化(第 9 篇:财务核算)
Day 78 → 重构 + 测试保命(第 10-11 篇:外科手术)
Day 85 → CR 文化(第 12 篇:康复训练)
Day 116 → 新系统免疫力(第 13 篇:预防医学)

**从"救火队员"到"公共卫生系统"——**这就是一个团队的品质工程成熟度。

# 10.4 速查一图

三张卡片,为新系统而生:

卡片 1:新系统 Day 1 必做四件事(住院医)

1. 分层骨架:Adapter/Application/Domain/Infrastructure 四目录
2. CI 门禁:build/test/coverage/sonar/pit/pr-size 六项
3. 三模板:PR / Issue / ADR
4. 观测闭环:结构化日志 + traceId + 至少 1 个 metric

卡片 2:免疫力五层护栏(架构师)

Layer 5 组织:招聘 · 培训 · 品质预算 · SLO
Layer 4 运行:观测 · 混沌工程 · 灰度 · 回滚
Layer 3 交付:CI 门禁 · 契约测试 · Preview
Layer 2 代码:分层架构 · 防腐层 · 契约
Layer 1 决策:ADR · MVP 定义 · 品质预算

卡片 3:API 契约五条硬规则(主治)

1. 向后兼容优先(只加字段,删字段走 6 月弃用)
2. 显式版本(/v1 /v2)
3. Idempotency-Key(幂等)
4. 错误码规范(code/message/traceId)
5. OpenAPI + Pact 契约测试

# 10.5 全文快速回顾

  • 第 1 章:新项目也难逃生病 · 前 5 天就出现坏味道
  • 第 2 章:六大早发病 + A11-A15 病案
  • 第 3 章:从 0 开始为何依然会烂 · 免疫缺失三大症状
  • 第 4 章:五层护栏 + 分层 + 契约
  • 第 5-7 章:三视角护栏建设
  • 第 8 章:30 天健康度对照
  • 第 9 章:A11-A15 归档 + 全专栏连接

# 10.6 核心要点串联

  1. 免疫从 Day 1 开始:越早越省
  2. 护栏分层建设:代码 / 架构 / 契约 / 流程 / 文化
  3. 契约先行:接口决定模块边界
  4. 度量托底:健康度必须可量化
  5. 文化承接:坏习惯不能带进新项目

# 10.7 常见误区汇总

  • ❌ 新项目'先跑起来再补测试'
  • ❌ 分层混乱,跨层直连
  • ❌ 接口先实现再补契约
  • ❌ 没有 CI 门禁就上生产
  • ❌ 老团队坏习惯直接带进新项目

# 10.8 带走清单总表

  • [ ] Day 1 定义分层与依赖方向
  • [ ] Day 5 CI + 门禁就位
  • [ ] Day 30 出健康度报告
  • [ ] A11-A15 表进 CR 模板
  • [ ] 团队坏习惯清单不带入新项目

下集提要:

  • 30 天后,NextDaySvc 的免疫力得到验证。
  • 12 篇专栏、62 个病案、5 位主角、90 天诊疗记录——是时候合上医生手册。
  • 第 14 篇《医生手册总结》——完结篇:把 13 篇内容抽成 3 张地图、7 个仪表盘、20 条铁律,让读者带走一本可以随时翻查的"代码医生手册"。

"下一次," 老陈合上笔记本,**"我们把整本手册压缩到一张纸上——**让每一位读到这里的工程师,从明天早会就能开始用。"

上次更新: 2026/07/16, 11:32:10
12.代码审查文化建设
14.医生手册总结索引

← 12.代码审查文化建设 14.医生手册总结索引→

最近更新
01
14.给3年前自己的一封信
07-21
02
13.技术债与遗产系统治理
07-21
03
12.技术团队建设能力
07-21
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 鄂ICP备2024073355号-1 | 鄂ICP备2024073355号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式