前言
代码质量对公司和个人都很重要。
对公司来说,公司期望高质量的产品。代码质量会直接体现到产品质量上。代码质量差往往会导致产品质量差。同时,公司期望开发产品的速度快。代码质量好,有利于提升开发速度。反之,改代码质量差的代码,就像在保持不塌的情况下,移动岌岌可危的乐高搭的高楼中的积木,速度快不起来。
对个人来说,代码质量是程序员专业能力的体现。能写出高质量的代码,有助于找到好工作和升职加薪。
因此,我们都期望提升代码质量。
提升代码质量的方法
提高代码质量的方法有很多,比如:
- 统一代码风格。
- 给文件,类,函数,变量等起有意义的名字。
- 在必要的地方加注释。
- 合理的使用编程方法论。DDD(领域驱动设计),面向对象编程,函数式编程。
- 合理的使用设计原则和设计模式。
- 写测试用例。
- 持续集成。
- 代码扫描。
- Code Review。
- 结对编程。
- 挑选高质量的第三方库。
- …
方法这么多,在时间和资源有限的情况下,我们该做哪些?以及做的先后顺序是怎样的?
提升代码质量的顺序
《学得会,抄得走的提升前端代码质量方法》系列文章是对上面问题的回答。
代码质量由 3 个部分组成:
- 实现业务功能。
- 代码的可读性。
- 代码的复杂度。
高质量的代码首先是实现了业务功能的,然后有很好的可读性,最后,代码的复杂度控制在一个可接受的范围。提高代码质量的方法,都可以归类为这 3 个部分。系列文章根据这 3 个部分,将代码质量从坏到好为 5 个阶段。如下图所示:
提升代码质量,应该从下层往上层做。
代码的价值在于实现业务功能。不能实现业务功能的代码,写的再好也没有价值。因此,代码首先要实现业务功能。
读代码是个高频操作。每次改代码前,都会读代码。同时,提升代码的可读性,成本不是很高。从投入产出的角度来看,提升代码可读性的性价比高。
最后,就是降低代码的复杂度。要降低代码的复杂度,需要花大量时间去做调研和设计,往往还会走一些弯路。
降低复杂系统的复杂度,对团队和个人来说,都是一个挑战。因此,把这块放到最后。
代码质量第 5 层 - 只是实现了功能
产品实现的功能是产品价值的体现形式。功能实现是基础。功能没有实现,其他方面做得再好也没有意义。
本文主要内容如下:
- 如何做到:实现的功能覆盖了需求。
- 仅仅实现了功能有什么问题。
如何做到:实现的功能覆盖了需求
要实现功能覆盖需求,需要团队不同角色的共同努力。如下图所示:开发人员自测
开发人员自测指:开发人员开发完后,自己测试功能是否可以全部实现。如果产品经理有出验收标准,则需要对着标准跑一遍。对前端来说,自测的内容主要是:功能,UI 交互和浏览器兼容性。
开发自测很重要。一方面,程序员自测,能更早的发现问题。越早发现问题,修复问题花的成本越低。另一方面,开发人员自测是对自己代码质量负责,也是专业素质的体现。没自测就提交测试,也浪费 QA 的时间。
建议将自测这块体现到工作流工具中。如果你用的是 CODING,可配置任务流转规则:状态流转到测试中时,一定要填写自测的内容:
QA测试
QA 会对功能做全面深入的测试:不仅测试正常的流程功能,还会测试异常流程,异常值,边界值等。因此,QA测试是对功能实现检查中很重要的一环。
专业的 QA 都会设计测试用例。测试用例完整的覆盖需求。QA 测试通过,就是要通过所有的测试用例。
当然,QA 测试也存在局限性:如果开发过程中引入的缺陷不在当前测试功能的范围内,QA 很有可能发现不了。要缓解这种局限性,有 2 个建议:
- 开发在提交测试时,告知 QA 可能会影响的其他功能。
QA 不管测试什么功能,测试完成后,都要再跑一遍产品所有模块最核心的测试用例。
产品经理验收
产品经理验收的是功能。产品经理对功能更敏感,容易发现漏做或实现的不对的功能。
设计师验收
设计师验收的是 UI 和交互。设计师有“像素眼”:能发现常人发现不了的 UI 问题。
仅仅实现了功能有什么问题
对于短期项目,仅仅实现功是没问题的。但现实中,很多是长期维护的项目。随着时间的推移,会加很多功能,也会改很多功能。项目会变得越来越大,越来越复杂。只管实现,不管代码的维护性。会加速的出现如下的问题:
增加新功能,改 bug 越来越难。花的时间也越来越长。
- 改了这个 bug,出现其他bug。
因此,对于长期项目,我们不仅要实现功能,还要注重代码的可维护性。我在下面的文章中会做详细介绍。
代码质量第 4 层 - 健壮的代码
健壮性(Robustness) 是指程序在遇到规范以外的输入,错误和异常时,仍能正常运行。简单来说,健壮代码的适应性很强,不会因为一些异常,就导致程序崩溃。
不健壮的前端代码体现为:
- 异常处理。
- 输入检查。
- 写法优化。
- 第三方库的选择。
1. 异常处理
不做异常做处理,轻则导致功能出错,重则导致页面白屏。异常处理,可以分为如下几种情况。
主动捕获运行时异常
try {
doSth()
await doSth2()
} catch (e) {
// 处理异常
}
处理意料之外的全局运行时异常
未被处理的 JavaScript 运行时错误(包括语法错误)发生时, window 会触发 error 事件。这么处理:
window.addEventListener(
'error',
(e) => {/* 处理异常 */}
)
当一项资源(如或