Skip to content

06 - 代码与评审:从代码写到合并的规矩 ​

代码是给未来的人读的,不是给现在的机器执行的。所以 Code Review 不是"挑错",是"教未来的人理解这段代码"。

一句话 ​

CI + Code Review + 测试 = 把代码质量门建在合并前,而不是上线后——一次慢的合并 ≈ 一次快的故障排查。

Git 工作流 ​

推荐:Trunk-Based Development(主干开发) ​

SE@Google Ch16 推荐:

"We find 'trunk-based development' as popularized by DevOps (one repository, no dev branches) to be a particularly scalable policy approach."

核心:

main (trunk)
  │
  ├─ feature/xxx ──┐
  │                │
  └─ feature/yyy ──┴→ merge 到 main

规则:

  • 永远从 main 开新分支
  • 1-2 天内必须合回 main
  • 长期分支 = 反模式
  • feature flag 让"已合并但未发布"成为可能

三种主流工作流对比 ​

维度Git FlowGitHub FlowTrunk-Based
长期分支develop + mastermain无
短期分支feature/*feature/*feature/short-lived
发布节奏版本发布持续部署持续部署
团队规模10+ 人5-30 人任何规模
学习成本中低低
推荐传统企业中小型现代化团队

小团队 → Trunk-Based:分支短(< 2 天),合并勤(每天多次)。

Commit 规范 ​

Conventional Commits(推荐) ​

<类型>(<范围>): <简短描述>

[正文]

[脚注]

类型:

  • feat: 新功能
  • fix: 修复 bug
  • docs: 仅文档
  • style: 格式(不影响代码)
  • refactor: 重构(既不是新功能也不是 bug 修复)
  • test: 测试相关
  • chore: 杂项(构建/工具等)
  • perf: 性能优化

示例:

feat(orders): 添加订单状态机

订单状态转换:待支付 → 已支付 → 已发货 → 已完成
新增 OrderStatus 枚举 + 状态校验

关联 Issue: #1234
关联 ADR: ADR-2026-Q3-001

🤖 Generated with [Claude Code](https://claude.ai/code)

为什么规范:

  • 自动生成 CHANGELOG
  • 自动判断版本号(semver)
  • 工具能识别和分类

反模式:垃圾 Commit Message ​

❌ "fix bug" / "update" / "WIP" / "最终版本" / "再改一下"

✅ "feat(orders): 添加订单状态机"

Pull Request 模板 ​

markdown
## 变更说明
[这段 PR 改了什么 + 为什么]

Closes #[Issue 编号]

## 改动类型
- [ ] 新功能
- [ ] Bug 修复
- [ ] 重构
- [ ] 文档
- [ ] 其他

## 测试
- [ ] 单元测试已通过
- [ ] 集成测试已通过
- [ ] 手动测试通过
- [ ] [其他测试]

## 验证步骤
1. [步骤 1]
2. [步骤 2]
3. [预期结果]

## 截图 / 录屏
[如有 UI 改动,附截图]

## 关联文档
- ADR:[链接]
- 设计稿:[Figma 链接]

## Checklist
- [ ] 代码遵循项目代码规范
- [ ] 没有遗留注释代码(`console.log`、`TODO`、`FIXME`)
- [ ] 没有无关改动
- [ ] 大函数已拆分(< 50 行)
- [ ] 复杂逻辑有注释

Code Review 规矩 ​

SE@Google Ch9 关键论断 ​

"Code Review is a mechanism for growing the team and the codebase simultaneously."

翻译:Code Review 既提升代码质量,也提升团队能力。

Review 的两个角色 ​

作者:

  • PR < 400 行(多了就拆分)
  • 自审(提交前自己看一遍 diff)
  • 自测(本地跑过测试)
  • 描述清晰(截图 + 验证步骤)

Reviewer:

  • 24 小时内响应
  • 关注:可读性 > 设计 > 细节
  • 评论要"建议"而非"命令"

关注优先级 ​

高(必看):
   业务逻辑正确性
   安全性漏洞(注入 / XSS / CSRF / 鉴权)
   数据一致性
   性能瓶颈
   可读性(命名 / 函数长短 / 职责清晰)

中(建议看):
   错误处理完整性
   日志是否充分
   测试是否够

低(看也行):
   代码风格细节
   命名细节
   注释风格

评论范式 ​

❌ 反模式评论:

"这段代码写得不好"
"应该这样写"
"重写吧"
"废代码"
"很丑"

✅ 高质量评论:

"这里如果传入 null 会怎样?建议在前面加 null check"
"我建议提取一个独立函数,可以提升可测试性"
"这里是不是用 Promise.all 并发更好?性能能提升 3 倍"
"建议加个测试覆盖边界情况(空数组)"
"这块跟 ADR-XXX 不一致,是否确认走的是新方案?"

SE@Google Ch9 重要原则:

"Treat incoming comments as questions, not commands."

翻译:把评论当"问题"而非"命令"——评论者不是权威,作者可选择不采纳并解释。

Code Review 反模式(10 种) ​

1. LGTM 农场 ​

症状:Reviewer 一句话不说就 Approve。

修复:

  • Review 工具统计:每个 Reviewer 平均评论数
  • < 0.5 个评论/人 = 警报
  • 必须留评论(包括 LGTM, 1 个疑问)

2. 等太久 ​

症状:PR 提交后 1 周没 Review。

修复:

  • 24 小时规则:所有 PR 必须 24h 内有人回应
  • 跨团队 PR:明确指定 Reviewer
  • 设 Reviewer On-call

3. 一次审 1000 行 ​

症状:PR 含 1000+ 行变动,Reviewer 看不动。

修复:

  • PR < 400 行(多了就拆)
  • 大重构用"分阶段合并"(多次小 PR)

4. 评论变命令 ​

修复:用问句而非命令("能不能这样"而非"必须这样")。

5. Reviewer 跟作者争论 ​

修复:作者解释理由 → 双方如果还不同意 → 团队 Lead / 架构师仲裁。

6. 不做自审 ​

症状:作者直接提交,Reviewer 第一遍看。

修复:

  • 作者先看自己 diff
  • 自查清单(命名前后一致 / 测试 / 文档 / 无 console.log)

7. 没有自动化门 ​

症状:Linter / 测试 / 构建靠人手运行。

修复:CI 自动跑所有门(见 07 部署章节)。

8. 评论太多(50+) ​

症状:PR 评论 50+,说明设计有问题。

修复:设计错误必须先合并设计 PR——代码 PR 是设计已确定的实现。

9. 个人风格当真理 ​

症状:争论 tab vs spaces、单引号 vs 双引号。

修复:用 Linter 强制规范——没有争议空间。

10. PR 长期不合并 ​

症状:PR 一直 In Review。

修复:5 天规则——超过 5 天未处理 = Rebase 或 Close(重新开)。

测试金字塔 ​

                  ┌───────────┐
                  │   E2E     │  10%    慢 + 脆
                  ├───────────┤
                  │Integration│  30%    中等
                  ├───────────┤
                  │   Unit    │  60%    快 + 独立
                  └───────────┘

SE@Google Ch11 测试原则 ​

测试的 5 个特性:

  1. 覆盖率不是目标——80% 覆盖率可能是无意义断言
  2. 测试也是代码——要维护、要 Review
  3. 测试金字塔——多单元 + 少集成 + 极少量 E2E
  4. 测试要快——单元 < 5 分钟跑完
  5. 测试要独立——不依赖外部系统(用 Test Double)

测试覆盖度的真正意义 ​

覆盖率是底线,不是目标:

  • 单元测试覆盖率 ≥ 70%
  • 关键路径 100%
  • 不要追求 100%(代价太高)

测什么:

  • ✅ 业务逻辑(订单状态机)
  • ✅ 边界条件(空数组/null/极值)
  • ✅ 异常路径(错误响应/超时)
  • ❌ Getter/Setter
  • ❌ 三方库代码

Mock / Stub / Test Double ​

Test Double 类型:

类型作用示例
Dummy填充参数,不调用null, new Object()
Stub返回预设值when(mock.foo()).thenReturn(42)
Spy记录调用验证某方法被调用过
Mock验证行为验证调用顺序和参数
Fake简化实现内存数据库

使用原则:

  • 外部依赖必须 Mock(DB / HTTP / 第三方 API)
  • 核心业务逻辑不要 Mock(那就是测 Mock 本身)

Lint + 静态分析 ​

Linter 强制规范 ​

让机器判断的事,不要让人判断:

javascript
// .eslintrc.js
module.exports = {
  rules: {
    'no-console': 'error',         // 禁止 console.log
    'no-debugger': 'error',        // 禁止 debugger
    'max-lines-per-function': ['warn', { max: 50 }],
    'complexity': ['error', 10],   // 圈复杂度不超过 10
    // ...
  }
}

Pre-commit Hook ​

bash
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.4.0
    hooks:
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-yaml
  - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
    hooks:
      - id: commitlint

关键:lint 失败不能合并——CI 自动化强制。

单仓(Monorepo)vs 多仓 ​

单仓(推荐 5-30 人) ​

优点:

  • 共享代码改动立即生效
  • 跨项目重构容易
  • 统一工具链

缺点:

  • 大仓慢(解决方法:稀疏 checkout / 部分克隆)
  • 需要权限管理

工具:pnpm workspaces / Turborepo / Lerna / Nx

多仓(推荐 30+ 人) ​

优点:独立部署、独立权限 缺点:跨项目改动困难

依赖管理 ​

SE@Google Ch21 关键原则:

"Be careful about dependencies. They're often the source of security, stability, and compatibility issues."

3 大依赖管理原则 ​

  1. 少用第三方——每多一个依赖 = 多一个风险源
  2. 锁版本——package-lock.json / go.sum 入版本控制
  3. 定期升级——安全更新必须及时(4 周内)

依赖审计 ​

每月运行:
1. npm audit / pip-audit / go list -m all
2. 处理所有 High / Critical 漏洞
3. 删除不再使用的依赖

每个季度:
1. 大版本升级评估
2. 替换不再维护的依赖

文档即代码 ​

代码内文档 ​

每个模块顶层要有 README:

markdown
# 模块名:订单服务

## 职责
订单的 CRUD + 状态管理

## 边界
- ✅ 包含:订单创建、状态查询、状态转换
- ❌ 不包含:支付(独立服务)、商品(独立服务)

## 关键类
- Order(聚合根)
- OrderItem(实体)
- OrderStatus(值对象)

## 依赖
- payment-service(支付回调)
- inventory-service(库存扣减)

## 测试
- 单元:src/__tests__
- 集成:tests/integration
- E2E:tests/e2e

## 关联文档
- ADR-XXX:选择 ORM
- PRD:订单需求文档

## Owner
- Tech Lead: 张三
- Product: 李四

进入下一章 ​

代码 PR 合并后,下一步:

  • 07 部署与运营——把代码变成用户可用的服务

作者:基于 SE@Google Ch9 (Code Review) + Ch16 (VCS) + Ch11-14 (Testing) 综合 最后更新:2026-06-28

从名家方法论与工程化思路中蒸馏出自己的工程体系。