第 1 章 整洁的代码 ........................................ 1
1.1 要有代码 ........................................... 2
1.2 烂代码 ............................................... 2
1.2.1 态度 ....................................... 3
1.2.2 难题 ....................................... 4
1.3 整洁代码的艺术 ............................... 4
什么是整洁的代码 ........................... 5
1.4 综述 ................................................... 6
1.4.1 代码为什么要整洁 ............... 6
1.4.2 生产力 .................................. 7
1.4.3 宜居性 .................................. 9
1.5 读比写多 ......................................... 10
1.6 童子军军规 ..................................... 11
第 一部分 代 码
第 2 章 清洁那些代码! .............................. 13
2.1 清洁过程 ......................................... 21
2.2 小结 ................................................. 26
2.3 附记:未来的鲍勃体验 Grok3 ...... 26
2.4 附记小结 ......................................... 28
第 3 章 首要原则 .......................................... 29
3.1 一切都要短小、命名得当、组织有序且排序合理 ............................. 29
函数 ................................................. 30
3.2 更明显的例子 ................................. 31
独立部署 ......................................... 48
3.3 最后的思考 ..................................... 49
第 4 章 有意义的名称 .................................. 50
4.1 使用表意明确的名称 ..................... 51
4.1.1 构建命名体系 ..................... 51
4.1.2 避免误导 ............................. 53
4.1.3 做有意义的区分 ................. 53
4.1.4 使用读得出来的名称 ......... 54
4.1.5 使用可搜索的名称 ............. 55
4.1.6 使用长度适宜的名称 ......... 56
4.1.7 避免使用编码..................... 57
4.1.8 使用恰当的词性 ................. 58
4.1.9 考虑关键词参数 ................. 59
4.1.10 别玩儿梗 .......................... 59
4.1.11 每个概念对应一个词 ....... 60
4.1.12 使用源自解决方案领域的名称 .................................. 60
4.1.13 使用源自所涉问题领域的名称 .................................. 60
4.1.14 添加有意义的上下文 ....... 61
4.1.15 不要添加没用的上下文 .................................. 62
4.2 小结 ................................................. 63
第 5 章 注释 .................................................. 64
5.1 弥补失败 ......................................... 64
5.1.1 隐藏或被遮掩的注释 ......... 65
5.1.2 撒谎的注释 ........................ 65
5.1.3 过于细节化的注释 ............. 66
5.1.4 注释不能美化烂代码 ......... 66
5.1.5 用代码阐释意图 ................. 66
5.2 好注释 ............................................. 67
5.2.1 法律信息 ............................. 67
5.2.2 信息量充足的注释 ............. 67
5.2.3 解释意图 ............................. 68
5.2.4 警示后果 ............................. 69
5.2.5 强调 ..................................... 70
5.2.6 公共 API中的Javadoc及同类文档 ............................. 70
5.3 烂注释 ............................................. 70
5.3.1 喃喃自语 ............................. 71
5.3.2 多余的注释 ......................... 71
5.3.3 误导性注释 ......................... 72
5.3.4 冗余和不精确 ..................... 72
5.3.5 循规式注释 ......................... 74
5.3.6 日志式注释 ......................... 75
5.3.7 噪声注释 ............................. 75
5.3.8 可怕的噪声 ......................... 77
5.3.9 TODO 注释 .......................... 77
5.3.10 能用函数或变量就不用注释 ................................... 78
5.3.11 位置标记 ........................... 78
5.3.12 归属与署名 ....................... 78
5.3.13 被注释掉的代码 ............... 78
5.3.14 HTML 注释 ....................... 79
5.3.15 非本地信息 ....................... 80
5.3.16 信息过多 ........................... 80
5.3.17 不明显的关联 ................... 80
5.3.18 函数头部注释 ................... 81
5.3.19 非公共代码中的Javadoc .............................. 81
5.3.20 示例 ................................... 81
5.4 小结 ................................................. 84
第 6 章 规范代码格式 .................................. 85
6.1 规范代码格式的目的 ..................... 86
6.2 纵向格式 ......................................... 86
6.2.1 概念间的纵向留白 ............. 87
6.2.2 纵向紧密度 ........................ 88
6.2.3 纵向距离 ............................ 88
6.2.4 变量声明 ............................ 89
6.2.5 相关函数 ............................ 90
6.2.6 概念关联性 ........................ 92
6.3 横向格式 ......................................... 92
6.3.1 横向留白与紧密度 ............. 93
6.3.2 横向对齐 ............................ 94
6.3.3 缩进 .................................... 95
6.3.4 违反缩进规则..................... 96
6.4 团队规则 ......................................... 97
6.5 鲍勃大叔的代码格式规则 ............. 97
第 7 章 整洁的函数 ...................................... 99
7.1 短小! ............................................100
7.1.1 好散文 ...............................100
7.1.2 每个函数一个抽象层级 ....101
7.2 自顶向下读代码:下梯规则 ........101
纠缠 ...............................................103
7.3 switch 语句 ................................103
7.4 深入探讨整洁的函数 ....................104
7.4.1 上下文相关 .......................105
7.4.2 可命名 ...............................106
7.4.3 被隔离 ...............................108
7.4.4 同质 ................................... 110
7.4.5 纯一 ................................... 111
7.4.6 部分纯一性 ....................... 113
7.5 小结 ................................................114
第 8 章 关于函数的经验之谈 .....................115
8.1 函数参数 ........................................115
8.1.1 可变参数 ........................... 116
8.1.2 参数多于 3 个? ................ 116
8.1.3 关键字参数 ....................... 117
8.1.4 标识参数 ........................... 117
8.1.5 输出参数 ........................... 118
8.1.6 错误码 ............................... 119
8.2 命令-查询分离 ............................. 119
8.3 使用异常替代返回错误码 ........... 120
8.3.1 责任自负 ........................... 120
8.3.2 抽离try/cache代码块 .... 121
8.3.3 错误处理就是一件事 ....... 122
8.3.4 错误码的依赖磁铁 ........... 122
8.4 DRY:别重复自己 ....................... 123
8.4.1 简单重复的代码 ............... 123
8.4.2 相似代码块 ....................... 124
8.4.3 循环重复 ........................... 127
8.4.4 偶合重复与本质重复 ....... 129
8.5 副作用 ........................................... 130
8.5.1 力有未逮 ........................... 130
8.5.2 函数式编程语言 ............... 131
8.5.3 面向对象编程语言 ........... 132
8.6 结构化编程 ................................... 133
8.6.1 顺序结构 ........................... 134
8.6.2 选择结构 ........................... 134
8.6.3 循环结构 ........................... 134
8.7 太多应牢记的事 ........................... 135
8.8 小结 ............................................... 135
第 9 章 整洁的方法 .................................... 136
9.1 把它改好 ....................................... 137
9.2 示例 ............................................... 138
考虑设计与架构 ........................... 150
9.3 小结 ............................................... 155
第 10 章 只做一件事 .................................. 156
10.1 提取方法重构 ............................. 157
不应置疑 ..................................... 158
10.2 到底什么是巨大函数 ................. 161
提取与类 ..................................... 174
10.3 小结 ............................................. 178
第 11 章 保持得体 ...................................... 179
11.1 报纸隐喻 ..................................... 180
保持得体 ......................................181
11.2 再谈下梯规则 ..............................182
11.3 抽象过山车 ..................................183
11.4 这么写,但不想这么读 ..............183
第 12 章 对象与数据结构 ...........................184
12.1 何为对象 ......................................185
12.2 数据抽象 ......................................185
12.3 数据/对象的反对称性 .................187
12.4 得墨忒耳律 ..................................189
12.4.1 火车失事 ........................189
12.4.2 混合结构 ........................190
12.4.3 隐藏结构 ........................190
12.5 数据传输对象 ..............................191
12.5.1 对象/关系“阻抗不匹配” ............................192
12.5.2 使用对象和数据结构 .....192
12.6 switch 语句 ..............................193
12.6.1 面向对象解决方案 ........195
12.6.2 别高兴得太早 ................196
12.7 选择面向对象还是选择过程式 ..............................................196
12.8 性能怎么办 ..................................197
12.9 小结 ..............................................197
第 13 章 整洁的类 .......................................198
13.1 类和模块与文件对比 ..................198
13.2 类应该包含什么 ..........................199
13.2.1 类设计的特征 ................199
13.2.2 经验与特征 ....................200
13.2.3 类什么时候算过大 ........201
13.2.4 代码中的策略 ................203
13.2.5 变更理由隐藏之处 ........203
13.2.6 修正问题 ........................204
13.2.7 一种过度开放的实现 ....206
13.2.8 该做点什么吗 ................207
13.2.9 现在怎么办 ....................207
13.2.10 闭合、高内聚、单一职责的类 ..................... 210
13.2.11 策略改变时 .................. 211
13.2.12 这算过度工程化吗 ...... 212
13.2.13 更简单的测试 ............. 212
13.2.14 接入 AI ........................ 213
13.2.15 它会犯错 ..................... 214
第 14 章 测试准则 ...................................... 215
14.1 准则 1:测试驱动的开发(TDD) ....................................... 216
TDD三法则 ................................ 216
14.2 准则 2:测试&&提交||回退(TCR) ........................................ 217
14.3 准则 3:小规模增量开发 .......... 218
14.4 设计 ............................................. 218
14.5 准则 ............................................. 219
14.5.1 枯燥、烦琐且低效........ 219
14.5.2 调试 ............................... 219
14.5.3 文档 ............................... 219
14.5.4 可靠性 ........................... 220
14.5.5 设计 ............................... 221
14.5.6 总结回顾 ....................... 221
14.5.7 天使与恶魔 ................... 221
14.5.8 驯服心魔 ....................... 222
14.5.9 复杂情况与漏洞 ........... 222
14.5.10 代价与影响 ................. 223
14.6 保持测试整洁 ............................. 223
14.7 测试赋能 ......................................224
第 15 章 整洁的测试 ...................................225
15.1 用于测试的领域特定语言 ..........228
15.1.1 组合断言 ........................228
15.1.2 组合测试结果 ................228
15.1.3 双重标准 ........................229
15.1.4 单一断言规则 ................230
15.1.5 单一执行规则 ................230
15.2 F.I.R.S.T. ......................................230
15.2.1 快速 ................................230
15.2.2 独立 ................................231
15.2.3 可重复 ............................231
15.2.4 自验证 ............................231
15.2.5 及时 ................................231
15.3 测试设计 ......................................231
15.4 小结 ..............................................232
第 16 章 验收测试 .......................................233
16.1 验收测试准则 ..............................233
16.1.1 准则 ................................235
16.1.2 持续构建 ........................235
16.2 小结 ..............................................235
第 17 章 AI、LLM 和天知道还有啥东西 ................................................236
17.1 用提示词编程 ..............................237
17.1.1 起步阶段 ........................241
17.1.2 斗胆盲猜 ........................241
17.2 小结 ..............................................244
第二部分 设 计
第 18 章 简单设计 ...................................... 246
18.1 YAGNI ......................................... 247
18.2 测试覆盖 ..................................... 247
18.2.1 渐进目标 ....................... 248
18.2.2 设计? ........................... 248
18.3 揭示意图 ..................................... 248
18.3.1 底层抽象 ........................250
18.3.2 测试:问题的后半部分 ...250
18.4 最小化重复 ..................................251
偶合重复 ......................................251
18.5 最小化规模 ..................................252
简单设计 ......................................252
第 19 章 SOLID 原则 ................................. 253
19.1 SRP:单一职责原则 .................. 254
19.1.1 偶合重复 ....................... 255
19.1.2 解决方案 ....................... 256
19.1.3 更高层级 ....................... 257
19.2 OCP:开放-闭合原则 ................ 257
19.2.1 思想实验 ....................... 257
19.2.2 方向控制 ....................... 260
19.2.3 信息隐藏 ....................... 260
19.2.4 小结 ............................... 260
19.3 LSP:里氏替换原则 .................. 260
19.3.1 LSP 与设计 .................... 261
19.3.2 出租车调度聚合平台 ..... 262
19.4 ISP:接口分离原则 .................... 263
19.4.1 ISP 与编程语言 ............. 263
19.4.2 ISP 与设计 ..................... 264
19.5 DIP:依赖倒置原则 ................... 264
19.5.1 稳定抽象 ....................... 266
19.5.2 工厂模式 ....................... 266
19.5.3 具体组件 ....................... 267
第 20 章 组件原则 ...................................... 268
20.1 组件 ............................................. 268
20.2 组件简史 ..................................... 269
20.2.1 可重定位 ....................... 270
20.2.2 连接器 ........................... 271
20.3 组件内聚性 ................................. 272
20.3.1 REP:复用/发布等价原则 ............................... 272
20.3.2 CCP:共同封闭原则 ..... 273
20.3.3 CRP:共同复用原则 ..... 274
20.3.4 组件内聚性张力图 ....... 275
20.3.5 小结 ............................... 276
20.4 组件耦合 ..................................... 276
20.4.1 ADP:无循环依赖原则 ............................... 276
20.4.2 SDP:稳定依赖原则 .....280
20.4.3 SAP:稳定抽象原则 .....284
20.5 小结 ..............................................287
第 21 章 持续设计 .......................................288
21.1 持续变更 ......................................289
21.2 持续设计 ......................................290
21.3 航行于持续设计的4C考量之上 ..............................................290
21.3.1 清晰性 ............................291
21.3.2 简洁性 ............................295
21.3.3 可验证性 ........................301
21.3.4 内聚性 ............................309
21.4 还需要在何时进行设计 ..............312
21.4.1 设计前置 ........................312
21.4.2 为工作做准备 ................312
21.4.3 开始工作 ........................313
21.4.4 做工作 ............................313
第 22 章 并发编程 .......................................314
22.1 为什么要并发 ..............................315
22.1.1 传言与误解 ...................316
22.1.2 挑战 ...............................316
22.2 并发防御原则 ..............................317
22.2.1 单一职责原则 ...............317
22.2.2 推论:限制数据的作用域 ............................317
22.2.3 推论:使用数据副本 .....317
22.2.4 推论:线程应尽可能独立 ................................318
22.3 了解你使用的语言和库 ..............318
线程安全工具集 ..........................318
22.4 了解执行模型 ..............................319
22.4.1 生产者-消费者模型 .......319
22.4.2 读者-写者模型 .............320
22.4.3 哲学家进餐问题 ...........320
22.5 警惕同步方法之间的依赖 ..........320
22.6 保持同步区短小 ......................... 321
22.7 正确的启动代码和关闭代码难以编写 ..................................... 321
22.8 测试线程代码 ............................. 321
22.8.1 将偶发失败看作潜在的线程问题 ....................... 322
22.8.2 先让非线程代码工作 ............................... 322
22.8.3 编写可插拔的线程代码 ............................... 322
22.8.4 编写可调优的线程代码 ................................323
22.8.5 运行比处理器数量多的线程 ................................323
22.8.6 在不同平台上运行 .......323
22.8.7 安插试错代码,尝试并强制代码失败 ...............323
22.9 2025 年实战更新及报告 .............325
数据完整性 ..................................325
22.10 小结 ............................................329
第三部分 架 构
第 23 章 软件的两大价值 .......................... 331
保留可能性 ............................................ 331
第 24 章 独立性 .......................................... 333
24.1 用例 ............................................. 334
24.2 运行 ............................................. 334
24.3 开发 ............................................. 334
24.4 部署 ............................................. 335
24.5 保留可能性 ................................. 335
第 25 章 架构的边界 .................................. 336
25.1 何时划定边界,划定怎样的边界 ............................................. 337
25.2 插件架构 ..................................... 338
25.3 案例研究:FitNesse ................... 339
25.4 小结 ............................................. 340
第 26 章 整洁的边界 .................................. 341
26.1 第三方物联网框架:诸多边界 ............................................. 341
26.2 用户界面/应用边界 .....................345
26.2.1 SOLID 原则与六边形架构 ................................347
26.2.2 探索和学习边界 ...........349
26.2.3 使用尚不存在的代码 .....351
26.3 整洁的边界 ..................................352
第 27 章 整洁的架构 ...................................353
27.1 依赖规则 ......................................354
27.1.1 实体层 ...........................355
27.1.2 用例层 ...........................355
27.1.3 接口适配层 ...................355
27.1.4 框架与驱动层 ...............355
27.1.5 只有4个圈层吗 ...........356
27.1.6 跨越边界 .......................356
27.1.7 什么数据会跨越边界 .....356
27.1.8 典型场景 .......................356
27.2 小结 ..............................................357
第四部分 匠 艺
“大量” .................................................. 359
80 多年 ................................................... 359
书呆子与救世主 ......................... 362
名声 ............................................. 362
榜样与恶棍 ..................................363
我们“主宰”世界 ......................364
灾难 ..............................................365
程序员誓言 .............................................366
第 28 章 有害 .............................................. 367
28.1 对社会无害 ................................. 368
28.2 对功能无害 ................................. 369
28.3 对结构无害 ................................. 370
28.4 柔性 ............................................. 371
28.5 测试 ............................................. 372
第 29 章 不损害软件行为或结构 .............. 373
29.1 把它改好 ..................................... 374
29.1.1 什么是好结构 ............... 374
29.1.2 艾森豪威尔决策矩阵 ..... 375
29.2 程序员是利益相关者 ................. 376
29.3 尽己所能 ..................................... 377
第 30 章 可重复证据 .................................. 379
30.1 迪杰斯特拉 ................................. 379
证明正确性 ................................. 380
30.2 结构化编程 ................................. 381
30.3 功能分解 ..................................... 383
30.4 TDD 及同类准则 ........................ 383
第 31 章 小周期 .......................................... 385
31.1 源码控制史 ................................. 385
31.1.1 打孔卡 ........................... 385
31.1.2 持续集成 ....................... 389
31.1.3 短周期 ........................... 389
31.2 持续集成 ..................................... 390
31.3 分支与功能开关 ......................... 390
31.4 持续部署 ..................................... 392
31.5 持续构建 ..................................... 393
第 32 章 持续打磨 ...................................... 394
32.1 测试覆盖率 ................................. 394
32.2 变异测试 ..................................... 395
32.3 语义稳定性 ................................. 395
32.4 清洁 ............................................. 396
32.5 创作成果 ......................................396
第 33 章 保持高生产力 ...............................397
33.1 黏性 ..............................................397
33.1.1 构建 ...............................398
33.1.2 测试 ...............................398
33.1.3 调试 ...............................399
33.1.4 部署 ...............................399
33.2 干扰管理 ......................................399
33.2.1 会议 ...............................399
33.2.2 音乐 ...............................400
33.2.3 心情 ...............................400
33.2.4 心流 ...............................401
33.3 时间管理 ......................................401
第 34 章 团队协作 .......................................403
34.1 协同编程 ......................................403
34.2 开放式办公室/虚拟办公室 .........404
第 35 章 靠谱和合理地估算 .......................405
35.1 谎言 ..............................................405
35.2 靠谱、准确、精确 ......................406
35.3 我的教训 ......................................406
35.3.1 故事 1:向量 ................406
35.3.2 故事 2:pCCU ..............408
35.3.3 教训 ...............................408
35.4 准确性与精确性 ..........................409
35.5 汇总 ..............................................410
35.6 靠谱 ..............................................410
35.7 压力 ..............................................411
第 36 章 尊重程序员同行 ...........................412
第 37 章 永不停止学习 ...............................413
后记 .................................................................415
附录 A 激辩《代码整洁之道》..................419
参考文献 .........................................................460