什么代码需要重构

  • 难以阅读, 就是可读性差。
  • 逻辑重复。
  • 添加新的行为需要修改已有代码。可拓展性差。
  • 带有复杂条件逻辑。
  • 需要提高性能
  • 开发效率低
  • 不易测试

重构以后的代码需要达到的目标是:

  • 提高可读性。
  • 相同的逻辑只出现一次。
  • 新的改动不会危及现有行为。提高可拓展性。
  • 尽可能简单地表达条件逻辑。
  • 能显著提高代码运行性能。
  • 提高开发效率,改进软件设计和分层。与可读性有些差异。
  • 能方便测试和查找bug。

    何时重构

  1. 平时开发时: 重复性工作,既有的代码无法帮助你轻松添加新特性时
  2. code review: 可以让他人来复审代码检查是否具备可读性,可理解性
  3. 测试时: 修补bug时,排查逻辑困难
  4. 交接时: 连自己都无法快速理清代码逻辑

    重构的衡量指标

  • 数量: 代码的行数
  • 质量: 代码复杂度,耦合度,可读性,架构依赖复杂度等
  • 成本: 花费的时间
  • 回报: 支持后续功能的快速叠加,解决现有因代码设计问题无法优化的矛盾, 提高了代码运行效率等

具体表现

  • 随着业务需求的不断加入,代码随着时间的推移变得越来越糟。
  • 这其中可能包括以下情况:
    • 重复的代码
    • 过长的函数
      • 遵循一条原则: 每当感觉需要注释来说明什么的时候,可以尝试将需要说明的东西写进一个函数中
    • 冗余的类
      • 当子类没有做足够的工作的时候,或者说在可见的预期内,不会有新的情况出现,考虑将类内联化。
    • 过长的类
      • 这种情况容易出现冗余代码。比如如果类内出现了多个变量带有相同的前缀或者后缀,这意味着你可以考虑把他们提炼到某个组件内,或者考虑这个组件是否可以成为子类,使用提炼类的手法来重构。

重构心得 - 图1

实例

纯react项目重构为redux + immutable.js

为什么重构

props自顶向下传递, 层级过深时:

  • 所有属性和回调重复编写在不相关的父层组件
  • 容易理解, 但是可读性差, 寻找方法和属性比较费劲
  • 定位错误不易, 调用链过长
  • 耦合度过高, 不易调试bug和测试
  • 性能较差, 不相关组件在别的组件状态刷新时也可能刷新, 只能手动用react生命周期去做优化

重构后的结果

改为redux + immutable.js后

  • 提取大部分组件状态到store, 批量管理
  • 提取操作状态的方法到reducer, 方便拓展, 易于追踪错误和测试
  • 结合不可变数据, 更细粒度的控制每个组件刷新状态, 提高性能
  • 方便了工作交接和统一开发规范
  • 为以后的项目积累经验

有什么代价

  • 花费时间多
  • 分层提高了理解门槛
  • 并不能完全重构, 不能重构的部分风格有差异
  • 性能提高有限

    何时不该重构

  • 如果代码过于混乱,甚至根本没有办法正常运行,这个时候与其花大力气重构,倒不如重写来的快。

  • 一个折中的方法是,将大的软件系统拆成多个子模块或子系统,然后分别对这些子模块或子系统进行重构或重写。
  • 还有一个情况是当项目工期临近终点的时候,如果时间来不及重构应该优先保证项目进度。
  • 我们常常把待重构的任务称为“技术债务”。类比现实生活中的债务,一个公司难免会有债务,而债务是要偿还的。当一个公司财务状况良好的时候,应该让自己的债务保持在一个健康的水平。但是当一个公司陷入泥潭,需要资金救急的时候,如果它手里有一笔钱,相比于还债,这笔钱更应该花在保证公司生存的事务上。

demo: https://juejin.cn/post/6844903866254049293 参考: https://juejin.cn/post/6844904114946572302