代码质量与规范,那些年你欠下的技术债

提到“质量”二字时,我们的第一反应往往是“有多少BUG?”“性能好不好?“这样的问题。我们对软件产品或服务的质量定义看其能不能满足用户的需求,包括功能、性能和体验等维度的指标,我们可以通过各种类型的检测手段来给出其质量高低的度量。但是,如果直接拿出一段源代码放在我们面前,问这段代码的质量好坏时,我们又该如何作答呢?

有人说:“好的代码就像好的笑话一样,它不需要解释(Good code is like a good joke: It needs no explanation)”。有编码经验的人对代码都有一定的“鉴赏力”,能凭感觉给出代码好坏的主观评价,看到所谓的“意大利面条式代码”都会感到不舒服,但是这样凭感觉的方式太个性化、太随意了,有没有一种公认的标准来鉴定代码质量呢?

Bob大叔在其著作《代码整洁之道》的前言中引用了这样一幅漫画:

图1代码质量的唯一有效度量指标

使用漫画中的“每分钟爆粗数量”来衡量代码质量是个很有趣的玩笑,强调了代码的可读易懂等这样的“内在”质量属性。相对于满足需求规范这样的“外在”质量属性,“内在”的代码质量属性强调的是支持实现功能需求的代码内部结构的质量。《Sonar code quality testing essential》一书中从七个维度定义了代码的这种内在质量,Sonar开发团队上纲上线的戏称为开发人员七宗罪:

编码规范:是否遵守了编码规范,遵循了最佳实践。

潜在的BUG:可能在最坏情况下出现问题的代码,以及存在安全漏洞的代码。

文档和注释:过少(缺少必要信息)、过多(没有信息量)、过时的文档或注释。

重复代码:违反了Don’tRepeat Yourself原则。

复杂度:代码结构太复杂(如圈复杂度高),难以理解、测试和维护。

测试覆盖率:编写单元测试,特别是针对复杂代码的测试覆盖是否足够。

设计与架构:是否高内聚、低耦合,依赖最少。

Martin Fowler在其著作《重构:改善即有代码的设计》中生动形象的使用“代码坏味道(Bad Code Smells)”来比喻低质量的代码设计和实现所显现的“症状”。书中罗列了22种代码坏味道以及对应的重构手法。

参照这些资料,现在我们可以用可测性,可读性,可理解性,容变性等代码可维护性维度的质量属性来衡量代码质量。代码质量指的是代码内在的非功能性的质量,用户不能直接体验到这种质量的好坏,代码质量不好,最直接的“受害者”是开发者或组织自身,因为代码质量好坏直接决定了软件的可维护性成本的高低,例如重复代码会造成维护成本的成倍增加;不规范的代码、不良注释和复杂度过高的代码会增加阅读和理解代码的难度,复杂度过高也会极大增加测试覆盖的难度,耗费过多人力,而缺少测试覆盖的代码会使得定位问题和修复问题的难度加大;结构不良、低内聚高耦合的代码则会使得哪怕是微小的需求变更或功能扩展都无从下手,修改的代价很可能超过了重写的代价。

至此,我们得到了一些定性的办法来衡量代码的质量,我们可以借助一些代码扫描工具来暴露代码的质量问题,也有了相应的重构方法和技巧来应对这些问题。但是,我们还是难以回答某段代码有多好或多差,两段代码相比哪个更好这样的问题,因为我们仍然没有完全解决代码质量的量化问题:同样都是代码质量问题,重复代码和过多注释的危害肯定是不一样的;同样都是方法太复杂,圈复杂度为10的方法和圈复杂度为20的方法相比,危害和修改难度也差别很大。所以我们不能直接用问题的数量来衡量质量,需要找到更精细合理的量化度量方法。

SQALE方法的质量模型

如何评估软件产品源代码质量一直是业界的一大挑战,SQALE(Software Quality Assessment based on Lifecycle Expectations)方法的出现提供一套科学的度量和分析方法,有效应对了这一挑战。SQALE方法整合了ISO-25010标准与代码规范,其目标是:以客观、准确、可复制和自动化的方式为评估软件应用程序的源代码提供支持;为管理技术债务提供一种有效的方法。SQALE是目前众多主流代码分析工具的参照标准,包括我们熟知的SonarQube,和CoderGears, SQUORE等商用代码扫描分析工具。

下面我们简单介绍一下SQALE方法的原理。SQALE方法包含两种模型:质量模型和分析模型。下图的树型结构展示了SQALE方法的质量模型:树根节点代表软件质量(此处即代码质量),从左向右展开,第一级定义了代码质量的特征分类,往下是每种特征的子类,最后是每个子类对应的属性/具体的度量项。

图2SQALE方法示意图(质量模型)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypgwf.html