团队中应当如何提升代码质量
代码质量其实是老生常谈的一个词,同时 质量 也是一个很主观的词,代码质量的好与坏究竟该如何评判,是否有一个定性和定量的标准,有了这个标准之后,在团队中间又将如何推动落地,希望这篇博文能够为你带来一点思路。
为什么要谈代码质量
很大一部分开发同学有一个认知,觉得代码 “能跑就行了”,写完自己多看一眼就会看不懂的代码之后,大手一挥完全不顾后来人的死活。
相信很多开发同学都碰到过这样的代码:
一个几百上千行的函数中间充斥着多年前留下来的古老注释与不明所以的分支逻辑,没有人敢删,也没有人敢改,所有业务知识全靠口口相传,新的需求如果要动到这段上古代码,就只能开始祈祷式编程,结果往往也是代码一动 bug 就来了。
如果你有共鸣,那我相信你内心其实是知道提高代码质量的必要性的,在我看来,提升代码质量的意义在于:
- 降低新人的学习成本
- 降低代码的后期维护成本
- 降低莫名其妙的 bug 出现率
- 增强编码人员对代码的信心
如何落地
在团队中的落地实践是我想重点谈一谈的,落地的过程中少不了硬性规定的实施与相关技能的培训,所以前期需要投入一定精力去建设质量保障体系,具体如下:
制定规范与标准
规范与标准的制定对于每个团队而言都大同小异,没有标准答案,关键是一定要在团队内部达成共识,在这里强烈建议参考《代码整洁之道》一书中的一到四章,熟读之后能够对规范的制定有一个更加具体的思路。这里我举几条之前公司的规范以供参考:
- 使用了
TypeScript
的项目,函数必须显式标明参数类型与返回值类型,void
除外 - 变量必须以驼峰形式英文命名,且不得有缩写的单词,行业或业务专有名词除外
- 变量命名需有明确的业务含义,不得以
info/data/list
这种毫无意义的单词进行命名
补充必要的单元测试
这里提到的单元测试(unit test)是指由开发人员在代码中去编写的测试,前端单元测试框架推荐 Jest,单元测试可以让你在阅读以前的代码时,多一个途径去了解相关的业务逻辑,同时也能够增强改动这段代码的信心。如果你对单元测试没有概念,可以参考以下这个示例:
1 | // 以下是业务逻辑 |
好的代码应当是自描述的,好的单元测试也是。以上这个单元测试做了两件事:
- 告诉阅读这段业务逻辑的人,这个分支下会做两件事情:给一个变量赋值、调用一个方法
- 保护这段业务逻辑不受重构的伤害,当你删除任何一行业务逻辑中的代码,这个单元测试就会运行失败
质量检查流程化自动化
当开发同学写完代码之后,我们又该如何去判断代码质量的高低呢?首先还是建议引入一些自动化工具来做这件事情,质量检查应当是一个持续的、轻量的过程,不应当也不可能花费太多人力成本在这件事上。检查的流程建议至少包含这三个阶段:
- 单元测试覆盖率检查
- lint 格式检查
- sonar 静态代码扫描
对于有 CI (如 Jenkins)相关基础设施的团队,可以充分利用持续集成的优势,为项目配置一条包含以上三个步骤的流水线,保证每次 push 代码之后都能够触发代码质量的自动检查。如果没有 CI 相关设施,可以利用 Git Hooks
在 push 的时候在本地进行质量的检查。有了定性的检查措施之后,流水线运行失败就意味着代码质量没有达到约定的标准,进而督促相关的开发同学对自己的代码进行改进。
定期代码检视(code review)
代码检视很有必要,但是很多开发同学都比较抵触,所以推动起来也不是一件容易的事,建议先降低频率,小范围试点推行。代码检视的形式个人更倾向于由 tech leader 主讲的集体检视,相较于一对一检视的优势有以下几点:
- 检视过程是业务传递的过程,可以让大家都了解小组内彼此的业务
- 当发现问题时,纠正的过程就是一次集体的知识传递,能够让成员都了解这个规则
代码检视的最终目的就是提高大家的代码质量,和上图一样,从 Bad code 到 Good code 的过程其实就是代码检视时 WTF 数量逐渐收敛的过程,当大家的代码质量逐渐提高,代码检视时遇到的问题也会逐渐减少。
写在最后
代码质量的提升必然是一个长期的过程,在这个过程中也许看不到即时收益,但是对于开发团队长期的发展而言是必不可少的,如果始终不去关注项目的代码质量,势必会导致技术债积压越来越多,到最后实在无法维护了,甚至需要重新立项进行整体的重构,到时就得不偿失了。
团队中应当如何提升代码质量