跳到主要内容

Code Smell

Mysterious Name

对类、模块、函数、变量的命名,需要使它们能清晰地表明自己的功能和用法

重构手法:

  • 改变函数声明
  • 变量改名
  • 字段改名

Duplicated Name

定义:在一个以上的地点看到相同的代码结构

重构手法:

  • 提炼函数——同一个类的两个函数含有相同的表达式

  • 移动语句——重复代码只是相似但时不完全相同

  • 函数上移——位于同一个超类中的不同子类

Long Function

每当感觉需要以注释说明点什么的时候,我们就需要把说明的东西写进一个函数里,并以其用途(而非实现手法)来命名

重构手法:

  • 提炼函数——大部分情况
  • 以查询取代临时变量——函数内有大量的参数和临时变量
  • 引入参数对象
  • 保持对象完整——将过长的参数列表变得简洁一些
  • 以命令取代函数——以上几种没有效果

How:

  • 分解条件表达式——条件表达式
  • 提炼函数——庞大的switch
  • 多态取代条件表达式——多个switch基于同一个条件进行分支选择
  • 拆分循环——提取出来的循环很难命名

Long Parameter List

重构手法:

  • 查询取代参数——如果可以向某个参数发起查询而获得另一个参数的值
  • 保持对象完整——从现有数据结构中抽出许多数据项
  • 引入参数对象——几项参数同时出现
  • 移除标记参数——某个参数被用作区别函数行为的标记
  • 函数组合成类——多个函数有同样的参数

Global Data

重构手法:

  • 封装变量

将全局数据使用一个函数包装起来,至少可以看到修改它的地方,并开始控制它的访问。最好把这个函数以及数据搬移到一个类和模块中

Mutable Data

重构手法:

  • 封装变量
  • 拆分变量——一个变量在不同时候被用于存储不同的东西
  • 移动语句和提炼函数——将处理更新操作的代码搬出来
  • 查询函数和修改函数分离——确保调用者不会调到有副作用的代码
  • 移除设值函数
  • 查询取代派生变量——可变的值能在其他地方计算出来
  • 函数组合成类雨和函数组合成变换——变量作用域只有几行代码
  • 将引用对象改为值对象——一个变量在其内部结构中包含了数据

Divergent Change

如果某个模块经常因为不同的原因在不同的方向上发展,就会出现Divergent Change

重构手法:

  • 拆分阶段——变化的两个方向形成了先后次序
  • 搬移函数——两个方向之间有更多的来回调用,应该创建合适的模块
  • 提炼函数——混合了前面两类处理逻辑,先提炼后搬移
  • 提炼类——如果模块是以类的形式定义的

Shotgun Surgery

如果遇到某种变化,你都必须在许多不同的类内做出许多小修改

重构手法:

  • 搬移函数
  • 搬移字段——常用操作
  • 函数组合成类——如果很多函数都在操作相似的数据
  • 函数组合成变换——如果有些函数的功能是转化或者是充实数据结构
  • 拆分阶段——如果一些函数的输出可以组合后提供给一段专门使用这些计算结果的逻辑
  • 内联函数
  • 内联类——把不该分散的逻辑拽回一处。内联后可以使用提炼相关方法继续重构

Feature Envy