代码质量第 1 层 - 可重构的代码

2021-12-23 22:30:51 浏览数 (1)

可重构的代码指:可以放心的改代码,不用担心因为改代码而导致 bug。可重构的代码的是对代码质量最高的要求,也是最难达到的。

可重构的代码是易于维护的。对于非可重构的代码,如果改了某模块,可能会导致一系列相关改动。如何找到改动会导致的影响?这不仅需要工作量,还有漏改导致的质量风险。

如何写出可重构的代码

写出可重构的代码要做 3 件事:

  1. 隔离副作用。
  2. 使用静态类型。
  3. 写测试。

隔离副作用是写出可重构代码的基础。使用静态类型是对过程的检查。写测试是对结果的检查。

下面具体来说。

1 隔离副作用

副作用指修改模块外的数据。常见的模块外的数据有:全局变量,Web Storage,DOM,组件间共享的数据,其他模块的内部数据。

在模块代码中,混入副作用代码会导致如下的问题:

  1. 副作用让代码变得难以测试。当模块依赖的外部数据发生变化后,模块的返回值可能会变化。这让模块的返回变得不稳定。
  2. 副作用会导致模块间的耦合。如果多个模块都依赖某个外部数据,那这几个外部模块之间是耦合的。多个模块改都可以改外部数据,数据流很混乱。
  3. 副作用让我们的系统变得不可预测。如果一个模块改了外部数据,可能会影响整个系统。

如何隔离副作用?方法是:

  1. 建一个数据中心来管理共享数据的获取和修改。模块获取和修改共享数据,需要用数据中心提供的 API。这样做降低了模块之间的耦合:当共享数据变化后,只需修改数据中心的逻辑。
  2. 模块需要修改其他模块的内部数据,要通过其他模块暴露的方法,而不是直接改值。
2 使用静态类型

使用静态类型可以规避很多低级的语法和逻辑错误,比如参数少传了,参数的类型传错了等。

代码语言:txt复制
function add(a: number, b: number) : number {
 return a   b
}
// 编译报错: 参数少传了。
add(3)
// 编译报错:参数的类型传错了。
add(3, '4')

修改某个 API 后,通过静态类型检查,我们可以知道,哪些调用的地方需要做对应的修改。

JavaScript 是个弱类型语言,不支持静态类型检查。可以用 TypeScript 来做静态类型检查。

3 写测试

这边的测试指的是白盒测试。

白盒测试又称结构测试、透明盒测试、逻辑驱动测试或基于代码的测试。白盒测试是一种测试用例设计方法,盒子指的是被测试的软件,白盒指的是盒子是可视的,即清楚盒子内部的东西以及里面是如何运作的。"白盒"法全面了解程序内部逻辑结构、对所有逻辑路径进行测试。"白盒"法是穷举路径测试。在使用这一方案时,测试者必须检查程序的内部结构,从检查程序的逻辑着手,得出测试数据。 -百度百科

测试可以保证测试覆盖部分的功能是总是正确的。代码修改后,只要测试用例能跑通过,则保证了代码改动没有破坏之前的功能。

测试是分层的。对前端来说,测试包括三层:

  1. 单元测试(Unit Tests)。
  2. 接口测试(Service Tests)。
  3. UI测试(UI Tests)。也叫端到端测试(E2E Test)。

单元测试主要针对的是方法,类和组件。接口测试主要针对的是后端接口。UI 测试主要针对UI和交互,属于集成测试。

Mike Cohn 在著作中《Succeeding with Agile》中提出了 测试金字塔 的概念。如下图所示:

我们写测试的数量,应该是:单元测试 > 接口集成测试 > UI测试。这主要考虑的是时间投入产出的性价比:

  1. 从测试金字塔模型可知:写单元测试花的时间少,写UI测试花的时间多。
  2. UI的改动频率比较高。每次 UI 改动,都需要改用例,成本很高。

我们写测试场景优先考虑:业务流程不频繁改动的核心场景。

总结

可重构的代码可以被放心的修改。要写出可重构的代码需要:

  1. 隔离副作用。
  2. 使用静态类型。
  3. 写测试。

至此,《学得会,抄得走的提升前端代码质量方法》系列就完结啦~ 前几期地址:

  • 前言
  • 代码质量第 5 层 - 只是实现了功能
  • 代码质量第 4 层 - 健壮的代码
  • 代码质量第 3 层 - 可读的代码
  • 代码质量第 2 层 - 可重用的代码

0 人点赞