新書推薦:
《
就业、利息和货币通论(徐毓枬译本)(经济学名著译丛)
》
售價:NT$
306.0
《
瘦肝
》
售價:NT$
454.0
《
股票大作手回忆录
》
售價:NT$
254.0
《
秩序四千年:人类如何运用法律缔造文明
》
售價:NT$
704.0
《
民法典1000问
》
售價:NT$
454.0
《
国术健身 易筋经
》
售價:NT$
152.0
《
古罗马800年
》
售價:NT$
857.0
《
权力与相互依赖(第四版)(中译本修订版)
》
售價:NT$
658.0
編輯推薦:
本书是敏捷技术教练和代码重构布道者Christian Clausen基于多年工作积累的实践经验编写而成,并且由世界级软件开发大师、设计模式和敏捷开发先驱Robert C. Martin (后辈程序员尊称其为“Bob大叔”)作序。Bob大叔在代码整洁方面为晚辈程序员奉献了3本代码整洁著作。本书是跟随Bob大叔脚步,站在巨人肩上,集大成写就的。它以代码
示例对比方式对好代码和坏代码进行识别,从重构、函数封装、类型设计、代码融合、数据维护等方面对程序员面临的问题进行深度分析。此外从编译器、注释及代码重构时机和方法等方面提出了一些策略和准则,教你在遇到问题时如何修复和改进低效代码,让你的代码变得优雅、易读和易维护。本书可作为对编程感兴趣的相关人员、程序员、计算机科学家和工程师的修炼宝典,是程序员提升自己的职业素养不可不读的经典著作。
內容簡介:
每个代码库都包含一些错误和低效之处,你需要将其找出并完成修正。以正确的方式进行重构,代码就会变得优雅、易读和易维护。在本书中,你将学习一种独特的重构方式,可以在5行或更少的代码中实现任何方法。你还会发现大多数资深开发人员都知道的一个秘密::有时敲定代码并在稍后进行修复会更快。 对所有技术水平的开发人员来说,本书是以全新视角审视重构。在本书中,你将掌握作者的创新方法,学习一些具体的规则,将任何方法简化为5行或更少。你将了解重构的时机、适用于大多数常见问题的特定重构模式,以及应该完全删除的代码特征。 ● 坏代码的标志 ● 在甚至不理解代码的情况下安全地改进它 ● 平衡优化和代码通用性 ● 正确的编译器实践
關於作者:
Christian Clausen是一名技术敏捷教练,主要教团队如何重构代码。
目錄 :
目 录
第Ⅰ部分
通过重构电脑游戏来学习
第1章 重构 3
1.1 什么是重构 4
1.2 技能:重构什么 5
1.2.1 代码异味示例 5
1.2.2 规则示例 6
1.3 文化:什么时候重构 6
1.3.1 在遗留系统中重构 7
1.3.2 什么时候不应该重构 8
1.4 工具:如何(安全地)重构 8
1.5 入门所需的工具 9
1.5.1 编程语言:TypeScript 9
1.5.2 编辑器:Visual Studio Code 9
1.5.3 版本控制:Git 10
1.6 总体示例:一款2D益智游戏 10
1.7 关于实际软件的说明 12
1.8 本章小结 12
第2章 重构的内部原理 13
2.1 提高可读性和可维护性 13
2.1.1 使代码更好 13
2.1.2 维护代码而不改变代码作用 15
2.2 获得速度、灵活性和稳定性 16
2.2.1 优先选择组合而非继承 16
2.2.2 通过添加而非修改来更改代码 17
2.3 重构与你的日常工作 18
2.4 在软件上下文中定义“域” 18
2.5 本章小结 19
第3章 拆分长函数 21
3.1 建立第一条规则:为什么是5行 22
3.2 引入重构模式来分解函数 24
3.3 分解函数以平衡抽象 32
3.3.1 规则:EITHER CALL OR PASS 32
3.3.2 应用规则 33
3.4 好的函数名称的属性 33
3.5 分解任务太多的函数 36
3.5.1 规则:IF ONLY AT THE START 36
3.5.2 应用规则 37
3.6 本章小结 39
第4章 让类型代码发挥作用 41
4.1 重构一个简单的if语句 41
4.1.1 规则:NEVER USE IF WITH ELSE 42
4.1.2 应用规则 43
4.1.3 重构模式:REPLACE TYPE CODE WITH CLASSES 45
4.1.4 将代码推入类 48
4.1.5 重构模式:PUSH CODE
INTO CLASSES 51
4.1.6 内联一个多余的方法 55
4.1.7 重构模式:INLINE METHOD 55
4.2 重构一个大的if语句 57
4.2.1 去除泛化 61
4.2.2 重构模式:SPECIALIZE METHOD 63
4.2.3 唯一允许的switch 65
4.2.4 规则:NEVER USE SWITCH 66
4.2.5 消除if 67
4.3 解决代码重复问题 69
4.3.1 不能用抽象类代替接口吗 71
4.3.2 规则:ONLY INHERIT FROM INTERFACES 71
4.3.3 所有这些代码重复是怎么回事 72
4.4 重构一对复杂的if语句 73
4.5 删除无用代码 76
4.6 本章小结 77
第5章 将类似的代码融合在一起 79
5.1 统一相似的类 80
5.2 统一简单条件 93
5.3 统一复杂条件 96
5.3.1 对条件使用算术规则 97
5.3.2 规则:USE PURE CONDITIONS 98
5.3.3 应用条件算术 100
5.4 跨类统一代码 101
5.4.1 引入UML类图描绘类关系 106
5.4.2 重构模式:INTRODUCE STRATEGY PATTERN 108
5.4.3 规则:NO INTERFACE WITH ONLY ONE IMPLEMENTATION 114
5.4.4 重构模式:EXTRACT INTERFACE FROM
IMPLEMENTATION 115
5.5 统一类似函数 118
5.6 统一类似代码 121
5.7 本章小结 125
第6章 保护数据 127
6.1 无getter封装 127
6.1.1 规则:DO NOT USE GETTERS OR SETTERS 127
6.1.2 应用规则 129
6.1.3 重构模式:ELIMINATE GETTER OR SETTER 131
6.1.4 消除最后的getter 133
6.2 封装简单数据 136
6.2.1 规则:NEVER HAVE COMMON AFFIXES 136
6.2.2 应用规则 138
6.2.3 重构模式:ENCAPSULATE DATA 143
6.3 封装复杂数据 145
6.4 消除序列不变量 152
6.5 以另一种方式消除枚举 155
6.5.1 通过私有构造函数进行枚举 155
6.5.2 将数字重新映射到类 157
6.6 本章小结 159
第Ⅱ部分 学以致用
第7章 与编译器协作 163
7.1 了解编译器 163
7.1.1 缺点:停机问题限制了编译时知识 164
7.1.2 优点:可达性确保方法返回 164
7.1.3 优点:明确赋值防止访问未初始化的变量 165
7.1.4 优点:访问控制有助于封装数据 166
7.1.5 优点:类型检查证明属性 166
7.1.6 缺点:取消引用null会使应用程序崩溃 167
7.1.7 缺点:算术错误导致溢出或崩溃 167
7.1.8 缺点:越界错误使应用程序崩溃 168
7.1.9 缺点:无限循环使应用程序停滞 168
7.1.10 缺点:死锁和竞争条件导致意外行为 169
7.2 使用编译器 170
7.2.1 使编译器运行 171
7.2.2 不要对抗编译器 173
7.3 信任编译器 178
7.3.1 教编译器不变量 178
7.3.2 注意警告 180
7.4 完全信任编译器 180
7.5 本章小结 181
第8章 远离注释 183
8.1 删除过时的注释 184
8.2 删除注释掉的代码 185
8.3 删除不重要的注释 186
8.4 将注释转换为方法名称 186
8.5 保留记录不变量的注释 187
8.6 本章小结 188
第9章 喜欢删除代码 189
9.1 删除代码可能是下一个前沿 190
9.2 删除代码以消除偶然复杂性 190
9.2.1 缺乏经验导致的技术无知 191
9.2.2 时间压力造成的技术浪费 192
9.2.3 环境造成的技术债务 192
9.2.4 增长带来的技术拖累 192
9.3 根据亲密程度对代码进行分类 193
9.4 删除遗留系统中的代码 194
9.4.1 使用绞杀者模式进行了解 194
9.4.2 使用绞杀者模式改进代码 196
9.5 从冻结项目中删除代码 196
9.5.1 将期望的结果设为默认 197
9.5.2 通过“探针并稳定”模式最大
限度减少浪费 197
9.6 在版本控制中删除分支 198
9.7 删除代码文档 199
9.8 删除测试代码 200
9.8.1 删除乐观测试 200
9.8.2 删除悲观测试 200
9.8.3 修复或删除不稳定测试 201
9.8.4 重构代码以消除复杂的测试 201
9.8.5 专门化测试以加快速度 201
9.9 删除配置代码 202
9.10 删除代码以消除库 203
9.11 从工作功能中删除代码 205
9.12 本章小结 206
第10章 永远不要害怕添加代码 207
10.1 接受不确定性:进入危险 207
10.2 使用探针实验克服对构建错误事物的恐惧 208
10.3 以固定比例克服对浪费或风险的恐惧 209
10.4 通过逐步改进克服对不完美的恐惧 210
10.5 复制和粘贴效果如何改变速度 211
10.6 通过可扩展性进行添加修改 211
10.7 通过添加修改可实现向后兼容 212
10.8 通过功能切换进行添加修改 213
10.9 通过抽象分支进行添加修改 216
10.10 本章小结 218
第11章 遵循代码中的结构 221
11.1 根据范围和来源分类结构 221
11.2 代码反映行为的3种
方式 222
11.2.1 在控制流中表达行为 223
11.2.2 在数据结构中表达行为 224
11.2.3 在数据中表达行为 227
11.3 添加代码以暴露结构 229
11.4 观察而不是预测且使用经验技术 229
11.5 在不理解代码的情况下获得安全性 230
11.5.1 通过测试获得安全性 230
11.5.2 通过掌握获得安全性 230
11.5.3 通过工具辅助获得安全性 230
11.5.4 通过正式验证获得安全性 231
11.5.5 通过容错获得安全性 231
11.6 识别未利用的结构 231
11.6.1 通过提取和封装来利用空白 231
11.6.2 通过统一来利用重复 233
11.6.3 通过封装来利用共同词缀 235
11.6.4 通过动态调度来利用运行时类型 236
11.7 本章小结 237
第12章 避免优化和通用性 239
12.1 力求简单 240
12.2 何时以及如何通用 241
12.2.1 最小化构建以避免通用性 242
12.2.2 统一稳定性相似的事物 242
12.2.3 消除不必要的通用性 242
12.3 何时以及如何优化 243
12.3.1 优化前重构 243
12.3.2 根据约束理论进行优化 245
12.3.3 使用指标指导优化 247
12.3.4 选择好的算法和数据结构 248
12.3.5 使用缓存 249
12.3.6 隔离优化代码 250
12.4 本章小结 251
第13章 让坏代码看起来很糟糕 253
13.1 用坏代码表明过程问题 253
13.2 分成原始代码和遗留代码 254
13.3 定义坏代码的方法 255
13.3.1 本书中的规则:简单而具体 255
13.3.2 代码异味:完整而抽象 256
13.3.3 圈复杂度:算法(客观) 256
13.3.4 认知复杂度:算法(主观) 257
13.4 用于安全破坏代码的规则 257
13.5 安全破坏代码的方法 258
13.5.1 使用枚举 258
13.5.2 使用整数和字符串作为类型代码 259
13.5.3 在代码中放入魔术数字 259
13.5.4 在代码中添加注释 260
13.5.5 在代码中添加空白 261
13.5.6 根据命名对事物进行分组 261
13.5.7 为名称添加上下文 262
13.5.8 创建长方法 262
13.5.9 给方法多个形参 263
13.5.10 使用getter和setter 264
13.6 本章小结 265
第14章 收尾工作 267
14.1 回顾本书的旅程 267
14.1.1 第I部分:动机和具体化 267
14.1.2 第Ⅱ部分:拓宽视野 268
14.2 探索基本原则 268
14.2.1 寻找更小的步骤 268
14.2.2 寻找底层结构 269
14.2.3 使用规则进行协作 269
14.2.4 团队优先于个人 269
14.2.5 简单性优先于正确性 270
14.2.6 使用对象或高阶函数 270
14.3 后续方向 271
14.3.1 微架构路线 271
14.3.2 宏架构路线 272
14.3.3 软件质量路线 272
14.4 本章小结 272
附录 为第Ⅰ部分安装工具 275
內容試閱 :
前 言
在我很小的时候,父亲就教我编程,因此自记事起我就一直在思考结构。我总是以帮助他人为动力;这就是我生命的意义。因此,教学很自然地吸引着我。当我在大学有机会获得助教职位时,我就立即接受了。
出于创业精神,我决定创办一个学生组织,它有助于学生互相辅导。这个组织欢迎任何人参加或发言,且主题范围广泛,包括从辅修课程中学到的知识到课程未包含的高级主题。我相信这样我就有机会讲授知识。但事实证明,计算机科学工作者都很羞怯,因此我不得不连续主持近60周才让组织运作起来。在此期间,我学到了很多,不仅有关我所教的课题,还包括有关教学方面的知识。这些讨论也吸引了一群求知欲很强的人,使我遇到了我最好的朋友。
大学毕业后的一段时间内,我和一位朋友一起出去玩。我们很无聊,朋友就问我是否可以即兴演讲,因为我已经做了很多这样的演讲。我回答说“让我试试” 。我们打开了一台笔记本计算机,一鼓作气输入了本书第Ⅰ部分的总体示例。
当我的手指离开键盘时,朋友十分震惊。他认为那是演示文档,但我有不同的想法:我想教他重构。
我的目标是让我的朋友在一小时后可以像重构大师一样进行编程。因为重构和代码质量是非常复杂的主题,所以我们必须假装具有大师级的重构能力。我查看了代码并试图找出一些规则,让朋友既能操作正确,又容易记住过程。在练习期间,即使我们是假装具有能力,朋友仍对代码做出了真正的改进。我们得到的结果非常好,朋友速度也很快,使得我当天晚上回到家后,立即写下了我们所讨论过的一切。当我们在工作中雇佣初级员工时,我重复进行了这个练习过程。慢慢地,我收集、构建并完善了本书中的所有规则和重构模式。
选定的规则和重构模式
完美不是无法再添加,而是无法再删除。
——Antoine de Saint-Exupéry
世界上有数百种重构模式,但我只介绍其中的13种。这样做是因为我相信深刻的理解比泛泛的熟悉更有价值。我还想打造一个完整的、有凝聚力的故事,因为它有助于拓宽视角并使主题更容易在脑海中组织起来。同样的道理也适用于规则。
太阳底下没有新鲜事。
——传道书
我并不是说本书中包含很多新颖观点,但我认为我是以一种既有趣又有利的方式进行了新的组合。许多规则源自Robert C. Martin的Clean Code (Pearson,2008),但我对此加以修改,使其更易于理解和应用。许多重构模式起源于Martin Fowler的 Refactoring(Addison-Wesley Professional,1999),但本书中的模式经过调整后,不再依赖强大的测试套件,而是能够借助编译器进行重构。
本书主要内容
本书由风格不同的两部分组成。第Ⅰ部分为重构奠定了坚实的基础,并且针对个人学习。相比全面性,我更关注学习的容易性。这部分适用于尚未有着坚实的重构基础的人,例如学生和初级或自学的开发人员。如果你查看本书的源代码并认为“这似乎很容易改进”,那么可以直接跳过第Ⅰ部分。
在第Ⅱ部分中,我更多地关注上下文和团队的学习。我选择了自认为在现实世界中最有价值的软件开发课程。一些主题主要是理论性的,例如“与编译器协作”和“遵循代码中的结构”;还有一些主题主要是实用性的,例如“喜欢删除代码”和“让坏代码看起来很糟糕”。因此这部分的应用范围更广,即使是有经验的开发人员也应该学习这些章节。
第Ⅰ部分的章节都使用一个单一的总体示例,因此这些章节紧密地联系在一起,应该逐一阅读。但是在第Ⅱ部分中,除了一些相互参考,这些章节内容基本上是独立存在的。如果没有时间阅读整本书,你可以根据自己的需要选择第Ⅱ部分中最感兴趣的主题单独阅读。
关于代码
本书包含许多源代码示例,包括编号列表和类似于普通文本的形式。在这两种情况下,源代码都被格式化为固定宽度字体,从而将其与普通文本区分开。代码的关键字加粗,以突出显示,使代码结构更易于理解。
在许多情况下,原始源代码已被重新格式化;我们添加了换行符和重新设计缩进,以顺应书中可用的页面空间。此外,当在文本中描述代码时,源代码中的注释经常被从列表中删除。许多代码清单都带有代码注释,突出了重要的概念。
本书示例的代码可从Manning网站(https://www.manning.com/books/five-lines-of-code)或我的GitHub仓库(https://github.com/thedrlambda/five-lines)下载获得,可扫描封底二维码下载源代码和彩图。