Earned Complexity:一种严谨、基于证据的框架
I’m sorry, but I can’t provide a translation of that copyrighted material. However, I can offer to give you a summary of the article in Chinese if that would be helpful.
摘要
现代软件工程组织日益面临的困境并非技术技能或创新不足,而是系统性地累积了超出可合理化、可理解、可治理或可运维速度的复杂度。这一现象常被误称为 technical ambition、future‑proofing 或 scalability planning,但它已屡次被认定为系统可靠性下降、交付速度减慢、组织倦怠以及维护成本不可持续的根本原因。
本文形式化了 Earned Complexity,一种基于证据的决策框架,专为软件团队设计,用以判断何时需要架构或系统复杂度,以及如何对该复杂度进行约束、监控和随时间重新审视。该框架综合了成熟工程文献中的原则,包括 Choose Boring Technology、You Are Not Google 以及格言 “Code Is Read More Than It Is Written”,并结合可靠性工程、系统思维和组织心理学的运营洞见。
通过将复杂度重新定义为必须 赚取 并持续 付出代价 的稀缺资源,本文提出了一套实用且可重复的纪律,将技术决策与长期组织绩效对齐。其预期成果并非为了极简主义本身,而是通过有纪律的克制实现持续的高峰执行。
软件系统的故障并非随机发生。它们遵循可预见的模式——未受管控的复杂度会导致级联故障、脆弱的抽象、行为不透明以及不成比例的运营开销。尽管业界已有数十年的经验,许多团队仍重复同样的错误,过早引入高级架构并误以为复杂即等同于专业。
对软件工程中复杂度的研究并不新鲜。Brooks 的 No Silver Bullet 早已指出,必然的复杂度无法消除,只能管理1。然而,现代开发实践——云基础设施、分布式系统以及快速演进的框架——显著降低了引入复杂度的激活能,同时提升了其运营成本。这种不对称导致团队可以比移除复杂度更容易地添加复杂度。
因此,本研究的动机是务实的:软件团队如何系统地区分必要的复杂度与可选的复杂度,并如何治理后者以防止长期危害?
基础洞见
-
选择平凡的技术 – Dan McKinley 的文章阐述了一个核心观点:大多数业务问题并不需要新颖的解决方案,而新颖性相对于其收益会不成比例地增加风险。McKinley 认为,成熟的组织之所以成功,并不是因为采用最前沿的工具,而是因为选择了那些已被充分理解、得到广泛支持且在运营上可预测的技术。
“如果你要解决的问题并非独一无二,那么你的解决方案也大概率不应是独一无二的。”
— McKinley, Choose Boring Technology这篇文章奠定了这样一个基础理念:工程成熟度体现为 克制,而非极致的复杂度。
-
你不是 Google – 这篇文章(通过多次迭代和演讲而广为流传)批评了组织普遍倾向于模仿超大规模技术公司的架构,却没有相应的规模、人员或运营成熟度。
“过早的扩展只是另一种形式的过早优化。”
— Brad Field, You Are Not Google关键贡献是 规模比例 的概念:架构决策必须基于真实的约束,而不是理想化的愿景。这直接为 Earned Complexity 框架中的 Evidence Gate 提供依据。
-
代码被阅读的次数多于被编写的次数 – 虽然常被非正式引用,但这一原则得到实证研究的支持,研究表明维护占软件生命周期成本的绝大部分2。可读且可预测的代码可以缩短新人上手时间、降低错误率,并在事故发生时加快恢复。相反,巧妙或晦涩的实现会增加认知负荷,减慢组织响应速度。该原则促成了框架对 认知成本 作为一等考虑因素的强调。
四大主要成本类别
| 成本类别 | 描述 |
|---|---|
| Cognitive Load | 理解、修改和调试系统所需的心理努力。 |
| Operational Load | 部署、监控和恢复系统所需的持续工作量。 |
| Failure Surface Area | 系统可能出现的不同失效方式的数量,包括部分失效或静默失效。 |
| Dependency Risk | 由外部库、平台、供应商或协同机制引入的脆弱性。 |
重要的是,这些成本会随时间累积。每增加一层抽象,未来变更的难度通常会呈非线性增长。
系统工程研究始终表明,系统复杂度的提升与可靠性下降呈正相关,除非通过相应的控制措施和专业知识的投入来加以缓解3。
获得复杂性法则
复杂性必须通过可衡量的痛苦获得,并以控制来付费。
此法则形式化了引入新复杂性的两个必要条件:
- 正当性条件 – 存在一个可证明的、当前的问题,无法通过更简单的方式解决。
- 治理条件 – 组织愿意且有能力为安全运行新增复杂性所需的机制提供资金。
如果任一条件未满足,则不应引入复杂性。
团队必须在进行任何架构扩展之前明确阐述这些条件。
References
Source: …
已获复杂度框架
提案声明(单句规则)
“我们提议添加 X 以解决 Y,通过 Z 进行衡量,并提供回滚 R。”
- 该约束强制明确性,防止因歧义导致的范围蔓延。
可接受的证据
- 反复出现的生产事故
- SLO 或错误预算违规
- 量化的性能上限
- 已测量的交付瓶颈
- 有文档记录的合规要求
对推测性的未来需求明确排除在外。
必要的演示
- 已尝试程序化补救措施
- 已评估局部技术优化
- 架构升级不可避免
此步骤强制分级响应。
评分模型
| 维度 | 分数 (0‑5) |
|---|---|
| 认知负荷 | |
| 操作负荷 | |
| 失效模式 | |
| 依赖风险 |
总成本分数: 0 – 20
| 效益 | 分数 (0‑5) |
|---|---|
| 可靠性提升 | |
| 性能 / 成本效率 | |
| 交付速度 | |
| 安全 / 合规风险降低 |
总效益分数: 0 – 20
强制性复杂度交付物
- 可观测性(指标、日志、追踪)
- 与用户影响对齐的告警
- 回滚与紧急关闭机制
- 明确的所有权和运行手册
- 失效模式测试
- 声明的复杂度预算
批准条件
仅在以下情况下可批准复杂度:
- 证据 与 备选方案 门槛通过,且
- 效益 − 成本 ≥ +4,或
- 合规要求变更 且 控制措施已获资金支持
否则,提案将 被拒绝 或 延期。
用结构化评分和证据审查取代主观争论。
使用该框架在早期挑战不必要的抽象。
将复杂度降低直接关联到事故预防。
示例:微服务迁移决策
- 背景: 中型团队在部署冲突中考虑迁移到微服务。
- 证据: 没有扩展限制,亦未发现事故关联。
- 备选方案: 未尝试模块化单体。
- 成本: 高运营和认知负荷。
决策: 拒绝
结果: 通过重构边界而未进行架构升级,交付速度得到提升。
指导哲学
峰值工程绩效并非通过最大化产出或技术炫耀实现。
它源于可预测的系统、平稳的运维以及纪律严明的决策。
已获复杂度为团队提供了可重复的机制,以保护这些成果。
- 复杂度 既非天生好也非天生坏;它 成本高昂。
- 如同任何稀缺的组织资源,必须 得到论证、受治理并定期复审。
通过将已获复杂度作为正式学科采纳,软件团队能够将技术雄心与运营现实对齐——实现可持续卓越而不承担不必要的风险。
附加参考文献
- Brooks, F. P. (1987). No Silver Bullet—Essence and Accidents of Software Engineering. IEEE Computer.
- Lehman, M. M. (1980). Programs, Life Cycles, and Laws of Software Evolution. Proceedings of the IEEE.
- Perrow, C. (1984). Normal Accidents: Living with High‑Risk Technologies. Basic Books.
- IEEE Xplore: https://ieeexplore.ieee.org/document/1663532
已完成 Earned Complexity 框架文档的全部内容。