大规模变更 = 放弃原子性,拥抱渐进性
解决什么问题:百万行代码无法一次提交—— 大规模变更 = 渐进式重构 + 工具支持 + Library Author 责任。
业务问题
真实场景
场景 1:原子性变更的局限
- 大型 monorepo = 数百万行代码
- 重构需要改 10000 个文件
- 一次提交 = 数小时 review + 数小时测试
- 合并冲突几乎必然
- "提交了反而无法 merge"
随着代码库增长:
- 原子性变更的能力反而下降
- 测试太慢
- Review 太难
- 合并冲突多渐进式重构(不是原子性)
原则:
- 每次提交小而可合并
- 持续演进
- 不破坏现有功能
工具:
- Refactoring scanner(自动找改动点)
- Mass-rename tool(批量重命名)
- Compat shim(兼容性垫片)Library Author 的责任
拥有 API = 负责演进
- 不破坏用户
- 提供迁移路径
- 弃用周期
- 自动生成迁移指南
工具:
- Auto-generated migration guide
- Compile-time warnings
- Refactoring hints in IDE4 类大规模变更
1. 语言级(如 C++11 → C++17)
- 编译器版本切换
- 兼容性标志
- 渐进式迁移
2. API 重命名
- 重命名工具
- 旧名保留为别名
- 弃用周期
3. 库升级(如 Guava 版本)
- 多版本共存
- API 兼容层
- 迁移指南
4. 架构迁移(如新 RPC 框架)
- Adapter 模式
- 灰度切换
- 双写双读工程实践
决策 1:何时用原子性 vs 渐进
决策:
- 改动 < 100 文件 → 原子性
- 改动 100-1000 → 看情况(可能原子)
- 改动 > 1000 → 渐进式
- 改动 > 10000 → 必须渐进 + 工具支持决策 2:渐进式重构的步骤
Step 1:识别所有改动点(工具)
Step 2:分批(按团队/按模块)
Step 3:每批 = 原子性提交
Step 4:测试 + Review
Step 5:合并 + 监控
Step 6:移除兼容代码反模式 vs 正模式
| 反模式 | 正模式 |
|---|---|
| 等全部改完再合并 | 渐进式提交 |
| 破坏用户 | 弃用周期 + 迁移指南 |
| 手动改 10000 文件 | 工具支持 |
| 单人完成 | 多人并行 |
与 L 层对位
关键洞察
- 原子性是规模的天敌——代码库越大,原子变更能力越弱。
- 工具 = 大规模重构的前提——没有工具支持别尝试。
- Library Author 责任 = 演进责任——不破坏用户。
- 渐进不是妥协——是工程纪律。
- 与 cybernetics 同构——Ch 18 自适应控制 = 大规模系统的演化能力。