重构: 改善既有代码的设计


date: 2022-04-05

  • 重构的前提

    • 重构的前提是有一套可靠的测试集

    • 好代码的检验标准是人们可以轻而易举的读懂并修改它

    • 重构过程中应时刻保持应用可以通过所有测试集

    • 重构时应清楚自己是在重构代码还是在添加新功能

  • 为何重构

    • 找到bug

    • 为了更易于理解设计

    • 为后续添加功能打基础

  • 何时重构

    • 添加新功能时

    • 为了帮助理解时

    • 发现问题时,记录下来有空再处理

    • 为了系统的健壮性,有计划的去重构

  • 何时不重构

    • 在需要理解内部详细情况下不重构

    • 如果重写比重构简单,那么重写

  • 坏代码

    • 神秘命名:不明白的意思的名称 -> 名称应与业务逻辑相关

    • 重复代码: 多个地方的逻辑是一样的 -> 整合重复代码

    • 过长的函数: 会让人不知道到底做什么 -> 提炼函数,命名规整

    • 过长的参数列表: 会让人疑惑 -> 使用结构

    • 全局数据: 容易被其他地方修改而不知

    • switch : 应使用多态来实现

    • 注释:应用命名代替注释,对于复杂的或者特别的可以注释说明

  • 编写测试用例的好处

    • 可以更清楚知道自己是否有bug

    • 更全局的考虑场景和代码吻合度

  • 如何编写测试

    • 针对某一特定功能 (容易错的地方)

    • 写特别有的针对性的用例

    • 用全局变量时注意多个用例共用时可能出现的问题

    • 有bug时,先写测试用例来暴露它,以便解决它

  • 重构建议

    • 尽量小步的重构,确保每个部位都是正确的

    • 注意多个方法使用同一个引用对象时发生的事情,可能超出你的意料

    • 在构建足够清晰的代码时,可以考虑使用内联或者提炼,让表达更清晰。

    • 当一个逻辑十分复杂时,考虑使用局部变量来让他简短而明了。

    • 封装数据时,考虑是否应该共享源数据。(不需要可以返回副本)

    • 将每个步骤区分开,提取各个步骤所需的公共数据,让逻辑更清晰

  • 重构方式

    • 封装:封装变量,定义类职责,思考应该暴露的概念,以及期望的效果

    • 搬移特性:将变量或方法定义在符合设计的地方,以便理解和合理建模

    • 重新组织数据:定义变量或者使用时候,要考虑到使用时如果被修改,可能造成的影响,比如在方法中传入对象,如果方法内修改了对象的内部变量值,可能影响其他使用者。

    • 简化条件逻辑:变量的逻辑判断给人的感受不如用文字表明的一个包装函数直观,适当使用断言帮助理解行为,使用多态来分解逻辑判断的难理解或共同点

    • 重构API:一个函数尽量制作一件事情,函数参数传变量还是对象基于函数作用考虑

    • 处理继承:将重复的代码尽可能移动到父类中。 不要过度设计导致滥用继承。继承应该作为具有相同行为的对象的一种抽象。 适当使用委托来减少过度的继承

一切都是为了便于理解。 本书6-12章讲述重构的手法,不一定都会用上,只是说明遇到某些情况,你可以使用它。 其他书籍 : 《修改代码的艺术》 《设计模式》

Last updated