重构 改善既有代码的设计 第二版 - Bad Smells in Code

重构 改善既有代码的设计 第二版 - Bad Smells in Code

  • 神秘的名字
    • Change Function Declaration
    • Rename Variable
    • Rename Field
  • 重复的代码
    • Extract Function
    • 代码类似但是不完全相同时Slide Statements
    • 如果重复代码位于公共父类的子类中Pull Up Method
  • 长函数
    • Extract Function
    • 使用Replace Temp with Query消除临时变量
    • 使用Introduce Parameter Object和Preserve Whole Object缩小参数列表
    • 如果还有很多临时变量和参数,就Replace Function with Command
    • 使用Decompose Conditional处理条件表达式
    • 把switch抽到一个函数
    • 如果多个switch语句的切换条件相同,使用Replace Conditional with Polymorphism
    • 把循环和循环体的代码抽出,Split Loop
  • 长参数列表
    • 如果询问一个参数,可以获得另一个参数,就使用Replace Parameter with Query删除第二个参数
    • 把很多数据放进一个已经存在的数据结构,Preserve Whole Object
    • 如果几个参数总在一起,就组合Introduce Parameter Object
    • 如果参数使用标记代表不同的功能,就Remove Flag Argument
    • 类是减少参数列表的好方法。特别是多个函数使用的参数相同时, Combine Functions into Class
  • GLOBAL DATA
    • Encapsulate Variable,观察它被修改的位置,控制对它的访问。尽量限制在类内或者模块内
  • 可变数据
    • Encapsulate Variable,修改易于监控,尽量缩小范围
    • 如果要被修改的变量保存不同的事情,使用Split Variable把他们拆开
    • 使用Slide Statements和Extract Function把无副作用的代码和修改的代码分开
    • 使用Combine Functions into Class和Combine Functions into Transform限制可修改一个变量的代码
    • 如果变量包含的数据有内部结构,使用Change Reference to Value替换整个结构
  • 分散的变化(因为不同的原因,一个模块以不同的方式改变),比如从数据库获取数据,再做财务处理
    • 使用Split Phase将两者分开,并在他们之间建立清晰的数据结构
    • 如果在调用过程中有很多来回,就创建适当的模块,使用Move Function划分处理
    • 如果函数混杂了两个类型的操作,在移动前使用Extract Function抽取
    • 如果模块是类,使用Extract Class
  • SHOTGUN SURGERY(和divergent change相反,每一个变化,都要修改很多类)
    • 使用Move Function和Move Field把他们移到一个模块
    • 如果一堆函数操作类似的数据,可以Combine Functions into Class
    • 如果很多函数转换或者enriching一个数据结构,可以Combine Functions into Transform
  • FEATURE ENVY(模块化程序的时候,我们希望将代码分成多个zones,最大化内部的交互,最小化之间的交互。当一个模块的某函数花费更多时间与另一个模块内的函数通信时,就是FEATURE ENVY)
    • Move Function
    • 如果只是函数的一部分,先Extract Function再Move Function
  • DATA CLUMPS(有些数据项总在一起)
    • Extract Class
    • 然后使用Introduce Parameter和Preserve Whole Object减少方法签名
  • 重复的switch
    • Replace Conditional with Polymorphism
  • LOOPS
    • Replace Loop with Pipeline。使用管道操作,比如filter和map
  • 临时属性(属性有时候有用)
    • 使用Extract Class,单独抽出来
    • Move Function,相关代码移过来
    • 使用Introduce Special Case消除条件代码。变量无效时创建替代类
  • 消息链(客户端为另一个对象询问一个对象)
    • Hide Delegate,把每个中间对象放进一个中间人
  • 中间人
    • 你看到一个类的一半方法委托给另一个类,就应该Remove Middle Man
  • 数据类(只有成员和get、set方法)
    • Encapsulate Record,不要有public成员
    • 对于不能修改的成员,Remove Setting Method
    • Move Function,get和set都移到该类
  • 拒绝接受(子类不想继承父类的某些方法)
  • 增加新的兄弟类,Push Down Method,Push Down Field

你可能感兴趣的:(重构)