不愧是疑问解决神器(二)!你强任你强👍👍👍
第3章 代码的坏味道
1.神秘命令(Mysterious Name)?
- 整洁代码中最重要的一环就是有一个好名字,使他们能够清晰地表明自己的功能和用法。
- 但正因为如此,命名就成了编程中最难的两件事之一。
- 而在重构中改名是最常用的重构手法,包括改变函数声明,变量名,字段名等。
- 记住,改名不仅仅是修改名字而已,若想不出一个好的名字,说明背后可能存在更深的设计问题。
2. 重复代码(Duplicated Code)?
- 最简单的重复代码就是在一个类或方法总,存在两个函数相同相同的表达式。
- 此时可采用提炼函数的方式来提炼出重复的代码,然后让重复调用这段代码的地方都改为同一个函数命名。
- 若重复的代码只是很相似,而不是晚安全相同,可尝试移动语句顺序来进行重组。
3. 过长函数(Long Function)?
-
活的最长,最好的程序,其中的函数都较短。
-
函数越长,就越难理解
-
但其实小函数也会给代码的阅读者带来一些负担,因为要经常切换上下文,才能看明白函数在做什么。若能给函数起一个好名字,阅读代码的人就可以通过名字了解函数的作用,根本不用去看函数的实现。
3.1 如何提炼函数的参数和临时变量?
- 可运用查询取代临时变量来消除临时变量
- 可使用参数对象的方式将过长的参数裂变的更简洁一些
- 若使用以上两种方式还是存在太多的临时变量和参数,那就上我们的杀手锏——以命令取代函数。
3.2 如何确定提炼某个文件下某一段的代码呢?
-
一个好技巧:寻找注释
- 注释可指出代码用途和实现手法之间的语义距离。若只有一行代码,还需要以注释来说明,那也值得将它提炼到独立的函数中。
-
遇到条件表达式和循环
- 如在将循环和循环内的代码提炼到一个独立的函数中时遇到难以为独立的函数命名,这可能是因为这段代码其中做了几件不同的事情。若是遇到这种情况,更要进行拆分。
4. 全局数据(Global Data)?
- 全局数据印证了帕拉塞尔斯的格言:良药与毒药的区别在于剂量。
- 少量对的全局数据或许无妨,但随着数量增多,处理的难度就会呈指数增长。
5. 可变数据(Mutable Data)?
- 在程序中,我们有时候修改了某一处的数据,然而却没有意识到软件中的另一处地方也在使用,或者另一处需要一个新的数据结构。
6. 发散式变化(Divergent Change)?
- 在程序设计中,我们都希望软件能够容易被修改,毕竟软件本身就是“软”的。
- 当我们要对某个上下文做修改时,我们只需要理解这个上下文,而不必操作另一个。
- “每次只关心一个上下文”这一点很重要
7. 霰弹式修改(Shotgun Surgery)?
-
霰弹式的修改类似于发散式变化,但却恰恰相反。
7.1 何为霰弹式修改?
- 如果当遇到某种变化,你都必须在许多不同的类中做出许多小修改,你所面临的坏味道就是霰弹式修改。
7.2 如何对霰弹式的程序进行修改?
- 可使用搬移函数,将所有需要修改的代码放进同一个模块中
- 如果有很多函数在操作相同的是数据,可将这些函数整合成类
- 常用策略是使用内联相关的重构,如内联函数,内联类等等,把本不该分散的逻辑组合在一处。
8. 依恋情结(Feature Envy)?
-
依恋情结的情况:比如一个函数跟另一个模块中的函数或数据交流很频繁。
8.1 何为模块化?
- 将代码分出区域,最大化区域内部的交互,最小化跨区域的交互。
-
8.2 有时候一个函数中往往会用到几个模块中的功能,那如何处理这种依恋情结呢?
- 可以判断哪个模块拥有的当前函数使用的数据最多,然后就可以把这个函数和数据放在一起。
9. 数据泥团(Data Clumps)?
-
数据项像小孩子一样,喜欢成群结队待在一起。
-
9.1 如何评判众多数据是否有价值?
- 删掉众多数据中的一项,然后看其他数据有没有因删掉的数据项而失去存在意义,如果不再有意义,那就是一个明确的信号,你应该为他们产生一个新对象。
10. 过长的消息链(Message Chains)?
-
何为过长的消息链?
- 一个用户向一个对象请求另一个对象,然后再想后者请求另一个对象,然后再请求另一个对对象,循环往复。
-
如何针对过长的消息连进行重构?
- 先观察消息连最终得到的对象时用来干什么的,看看能否以提炼函数把使用该对象的代码提炼到一个独立的函数中,再运用搬移函数把这个函数推入到消息链中。
- 如果还有许多客户端代码需要访问链上的其他对象,同样添加一个函数来完整此事。
11. 注释(Comments)?
- 注释并不是一件坏事,有时候它还是一个好事。
- 当你感觉需要编写注释时,请先尝试重构代码,试着让所有注释都变得多余。
第4章 构筑测试体系
1. 自测试代码的价值?
-
能够确保所有测试都完全自动化,让他们检查自己的测试结果。
-
当完成一个功能后,就开始编写测试代码可以更好的提高开发效率。
-
一套测试就是一个强大的bug侦测器,能够大大缩减查找bug所需的时间。
-
将测试代码的习惯提炼成一个技艺?
- 这个技艺就是测试驱动开发(Test-Driven Development, TDD)
-
测试驱动开发的短循环?
- 先编写一个测试 —> 编写业务代码 —> 重构。然后这个 “测试、编码、重构” 这个循环在我们日常开发中要完成很多次。
2. 本章所讲的内容?
- 带着你走进自测试代码世界的大门,从简单的例子开始。
第5章 介绍重构目录
1. 重构的记录格式?
-
每个重构手法都有 5 个部分
- 名称(name):建构一个重构词汇名称的对应表
- 速写(sketch):帮助我们更快的找到所需要的手法
- 动机(motivation):会介绍 “为什么需要做这个重构”和 “什么情况下不该做这个重构”
- 做法(mechanics):如何一步一步进行重构
- 范例(examples):以一个简单的例子来说明此重构手法如何运作
-
牢记重构的一点:小步前进,情况越复杂,步子就要越小