重构:改善既有代码的设计 第三章 读书笔记
目录 代码的坏味道
3.1 神秘命名(Mysterious Name)
需要好的命名方式,有意义的命名方式
3.2 重复代码(Duplicated Code)
场景 | 方法 |
同一个类中出现重复代码 | 提取重复代码到一个函数中 |
重复代码在一个超类的不同子类中 | 函数上移 到 父类中 |
重复代码出现在无关的类中 | 把重复代码抽取到额外的一个类中 |
重复代码只是相似而不是完全相同 | 移动语句:把重复的代码合并在一起,然后再抽取 |
3.3 过长函数(Long Function)
1- 抽取函数;
2- 减少临时变量:使用查询取代临时变量;
3- 减少参数个数;
4- 如果参数个数太多;
采用参数对象(固定的几个参数同时出现,又称“数据泥团”,提取成一个类)
保持对象完整进行简化(使用原有对象,而不是传输对象中的成员);
3.4 过长参数列表(Long Parameter List)
1- 查询取代参数; 2- 保持对象完整,直接传入原有的数据结构; 3- "数据泥团"参数包装成对象; 4- 如果某个参数被用作区分函数行为的标记;使用移除标记参数;
3.5 全局数据(Global Data)
手段:封装变量。
把全局数据用一个函数包装起来,至少你 就能看见修改它的地方,并开始控制对它的访问。
随后,最好将这个函数(及其 封装的数据)搬移到一个类或模块中,只允许模块内的代码使用它,从而尽量控 制其作用域。
3.6 可变数据(Mutable Data),这个内容比较多,需要好好消化
缺点:类似于全局数据;
手段:1- 封装变量; 可以很好的看见修改它的地方
2- 如果一个变量在不同时候被用于存储不同的东西, 可以使用拆分变量将其拆分为各自不同用途的变量
3- 移动变量,将没有副作用的代码与执行数据更新操作的代码分开
4- 使用将查询函数和修改函数分离
5- 查询取代派生变量
3.7 发散式变化(Divergent Change)
定义:如果某个模块经常因为不同的原因在不同的方向上发生变化,发散式变化就 出现了。
方法:
1- 两个模块有先后次序:拆分将两者分开;两个模块之间通过一个清晰的数据结构进行沟通;
2- 两个模块之间来回调用:创建适当的模块,然后用搬移函数把处理逻辑分开;
3- 函数内部混合了两类处理逻辑:应该先用提炼函数(106)将其分开,然后再做 搬移。
4- 如果模块是以类的形式定义的,就可以用提炼类来做拆分。
3.8 霰弹式修改(Shotgun Surgery)
表现:必须在许多不同的类内做出很多小修改;
方法: 1- 搬移函数和搬移字段,把所有需要修 改的代码放进同一个模块里。
2- 如果有很多函数都在操作相似的数据,可以使用函数组合成类;
3- 面对霰弹式修改,一个常用的策略就是使用与内联(inline)相关的重构—— 如内联函数或是内联类——把本不该分散的逻辑拽回一处。