重构方法介绍:

重构改善既有代码的设计

一 重新组织函数

  • 关于注释:要尽可能少的使用注释 , 注释越多代码的可读性反而更差,注释可以使用函数名来代替 , 不要管函数名有多长, 即使函数名比函数中的代码还要长也不要紧 ;
  • 提炼函数: 整理函数, 使函数恰当的封装代码 , 函数可以有效的替换注释。太长的函数会包含大量的信息 , 代码的可读性变得很差, 而且注释会很多 ,每隔一段都要添加一行注释,这样可读性变得很差 。比如,我们在一个方法中相关的代码进行了注释 ,这里我们就可以将这些相关代码提取出来 , 封装到一个函数中, 使用函数名将这段代码想要执行的动作表达出来。这种手法叫做“提炼函数”。
  • 内联函数:与提炼函数相反的方法是“内联函数”,内联函数就是将函数中的代码替换到函数调用的位置。在提炼函数的过程中,函数的粒度太细,函数没有做实质性的东西,可以将函数还原到代码中。
  • 处理局部变量:提炼函数最大的难题就是处理局部变量。一些简单的局部变量可以使用“以查询取代临时变量”来解决;对于那种多次复用多次赋值的变量,如果这个变量不是循环需要的变量,也不是用于统计结果的变量,变量的两次赋值没有关联,可以设置两个变量,分别替换复用的变量;对于更加复杂的局部变量,可以将方法提取成一个类,这是提炼函数的终极绝招。
  • 移除对参数的赋值:在函数中不要对参数进行操作,如果我们需要对参数操作,可以设置一个临时变量接收参数的值,对这个临时变量进行操作。
  • 替换算法:函数重新组织之后,如果发现算法可以经过改进,能更加明确的表明函数的意义,可以将这个算法替换;


二 在对象之间搬移特性

  • 功能模块归属类:对象设计中, 将一个功能模块放在哪个类中,是最重要的任务之一,谁也不能一开始保证设计的是完全合适的,这就需要“对象之间搬移特性”这个重构方法。
  • 搬移函数和搬移字段:这两种重构方法都可以解决大多数的问题,如果两种方法同时使用,先搬移字段,在搬移函数。
  • 提炼类和将类内联化:如果一个类承担责任过多,会变得臃肿不堪,这种情况下可以将一部分功能模块分离出去,提炼出另一个类;如果一个类的功能模块太少,这个类很小,可以将类内联化,将这个类合并到其它功能类似的类中。
  • 隐藏委托关系和移除中间人:当用户通过一个类调用另一个类时,要使用另一个类的功能的时候,为了实现更好的封装,可以隐藏委托关系,在服务端添加一个委托函数,使用户直接访问这个类,屏蔽用户对委托关系的了解;如果用户经常通过这个类访问其他的类,每个访问都要加上一个委托函数,如果这种过程过于复杂,我们可以将中间人移除,取消委托关系,与隐藏委托关系是相对的。
  • 引入外加函数和引入本地扩展:当我们想要将一个功能添加给类的时候,不能对该类进行操作,可以引入外加函数;当添加的功能很多的时候,可以将这些想要添加的功能放在一个类中,我们整体引入这个类,即引入本地扩展。


三 重新组织数据

  • 自封装字段: 就是给类中的私有成员变量加上get , set方法 , 注意添加的get , set方法没有修饰符 , 要与下面的封装字段区分开 . 关于通过何种方法访问类中的数据 , 一直存在争议 . 可以先使用直接访问的方法来访问 , 如果出现问题 , 就通过函数在访问类中的字段 .
  • 以对象取代数据值: 在编程过程中经常使用一个简单的数值表达某个概念 , 我们可以创建一个对象来表达这个改变 , 将哑的数据变成了善于表达的对象 , 可以使程序变得更优美 .
  • 以对象取代数组 : 如果发现一个数组的的行为方式很像一个数据结构 , 可以把数组变为对象 , 并添加该数组对应的行文方法 , 使数据结构更加清晰的显露出来 .
  • 魔法数: 带有特殊含义的数字 , 应避免魔法数的存在 , 使用常量来代替魔法数 .
  • 单向关联和双向关联: 类之间的关联就是在一个类中 , 定义一个另一个类的对象作为成员变量 ; 单向关联就是在一个类中存在另一个类的成员变量 , 另一个类中没有该类成员变量 ; 双向关联就是在两个类中同时存在另一个类的对象作为成员变量 .  单向关联的情况下 , 如果我们需要一个反向指针 , 例如客户和订单 , 我们需要知道一个客户有多少订单 , 同时又想知道这个订单属于哪个客户 , 这样我们就需要将单向关联转为双向关联 . 大量的双向关联会导致很多僵尸对象 , 一个对象已经没有用处了 , 但是有其它类中定义了改对象作为成员变量 , 这样我们就需要将这个双向关联改为单向关联 ;
  • 复制被监视数据: 有时用户界面中会处理业务逻辑相 , 为了将业务逻辑移动到合适的领域类中 , 需要在领域类中保存业务逻辑相关的数据 , 这里的重复的数据时不可避免的 , 分层的优先级要大于数据重复 .
  • 封装字段,封装集合,以数据类取代记录: 封装字段与自封装字段类似 , 但是又有所不同 , 给一个公共的成员变量添加get和set方法 , get和set方法的修饰符是public . 封装集合 , 对于集合的封装 , 应该尽量避免将整个集合暴露给用户 , 最好是将查询方法 , 添加 , 删除集合中的元素的方法暴露给用户 . 以数据类取代记录 , 在编程环境中有许多记录型结构 , 要想操作这些记录型结构就需要创建一个接口类 , 用来处理这些外来数据