本文从研发角度探讨下高质量软件应具备哪些特点,以及如何度量软件质量。
软件质量的分类
软件质量通常可以分为:内部质量和外部质量。
内部质量
内部质量是指软件的结构和代码质量,以及其是否适合维护、扩展和重构。它关注的是软件本身的特性和属性,包括:
- 可读性:代码易于阅读和理解;
- 易维护性:代码易于修改和维护;
- 可测试性:代码易于编写单元测试并进行自动化测试;
- 可靠性:代码稳定、不容易崩溃或出现错误;
- 可扩展性:代码能够方便地进行扩展;
- 可重用性:代码可被复用于其他项目中。
内部质量直接影响软件的可维护性和开发效率。如果软件的内部质量很差,那么开发人员可能需要花费更多的时间修复问题,而不是开发新功能。
外部质量
外部质量是指软件的用户体验和其符合用户需求的程度。它关注的是软件的功能和表现形式,包括:
- 功能性:软件是否具有所需的功能,并且这些功能是否能够正常工作;
- 易用性:软件是否易于使用,是否符合用户的期望;
- 性能:软件是否运行快速并响应迅速;
- 兼容性:软件是否能够在不同的操作系统和设备上正常工作。
外部质量如果很差,那么用户在使用软件过程中可能会遇到问题,而这些问题可能会影响用户体验,导致用户流失。
为什么内部质量更重要
内部质量高的核心降低了未来变更的成本。
可以参考下图的时间-功能累计关系图。
对于内部质量比较差的软件,虽然初期进展迅速,但是随着时间的流逝,添加新功能变得越来越困难。甚至一个小改动也需要程序员理解大量代码。当开发做代码变更时,还可能产生意想不到的缺陷,因此导致测试时间长,需要更高成本来做缺陷修复和验证。
对于内部质量高的软件,则与其相反,可以参考下图的比较。
内部质量高的软件更容易被实现。
内部质量高的软件特点之一就是易读性。 这样利于开发者更快弄清楚应用程序是如何运行的,这样就可以知道如何添加新功能。如果将软件很好地划分为不同的实现模块,则开发者没必要阅读所有代码,只需要快速找到涉及功能变动模块的代码就行。
如何衡量软件质量
Cyclomatic Complexity(圈复杂度)
Cyclomatic Complexity通过计算代码中不同路径的数量来衡量代码的复杂程度。圈复杂度越高,表示代码的控制流程越复杂,可能存在更多的错误和缺陷。
下面举例说明Cyclomatic Complexity如何计算。
public int calculate(x, y) { if (x >= 20) { if (y >= 20) { return y; } return x; } return x + y; }
这段代码的流程图如下:
圈复杂度的公式如下:
E - N + 2
其中 E 表示图中的边数(上图中的所有形状),N 表示节点数(上图中的所有箭头)。因此,在我们的例子中,6 - 5 + 2 = 3,的确这段代码包含三条路径。
Maintainability Index(可维护性指数)
Maintainability Index(可维护性指数)是一种用于评估软件代码可维护性的指标。它通常考虑代码的复杂度、长度和注释等因素,并将这些因素整合成一个分数来衡量代码的可读性、可维护性和可重构性。
通常情况下,可维护性指数的分数范围是 [0,100],分数越高表示代码的可维护性越好。可维护性指数可以帮助开发人员识别哪些代码需要改进,以提高代码的可维护性和可读性,从而减少维护成本、降低缺陷率,提高代码的质量。
Dependencies(依赖)
软件的开发过程势必会依赖外部框架和库,这些框架和库自身也会经常更新(维护者会添加和删除功能、修复错误、改进性能,并修补安全漏洞)。
旧版本库和框架通常会对依赖它的软件质量产生负面影响。例如安全漏洞是明显的风险(例如22年8月份的
Apachelog4j漏洞)。
SQALE评估法
SQALE评估法主要关注四个指标:
- 技术债:即未来要花费的时间和资源去修复当前存在的问题
- 可维护性:即代码的易读性、可理解性和可扩展性,从代码的模块化程度、命名规范、注释等因素,并对这些因素进行打分。
- 可靠性:即软件的稳定性和可靠性,评估代码中存在的错误、漏洞和异常处理情况。如果存在较多的问题,他们就需要考虑重新设计代码或增加更多的测试用例。
- 性能:即软件的响应速度和处理能力