Mamdouh Alenezi 在论文《Software Architecture Quality Measurement Stability and Understandability》中整理了一些论文中提到的软件架构衡量标准和颗粒度定义,参见下表:
颗粒度包括 包/类/方法,组件/库,架构三大类
Dwarak Govind Parthiban在论文《Examination of tools for managing different dimensions of Technical Debt》 中将技术债维度定义为:
代码实现(Code Debt)、组件设计(Design Debt)、架构设计(Architecture debt)和基础设施(Infrastructure Debt)
在 Bob 大叔的《Clean Code》中,函数、类、对象和数据结构、边界、单元测试等都有专门的介绍,结合 IOS/IEC 25010 中对于 Maintainability 的定义,以及一些代码检查工具对扫描规则的定义,列举了一些常见的代码实现层面相关的指标:
指标 | 计算方法 | 指标说明 |
---|---|---|
圈复杂度 | 参考 PMD: CyclomaticComplexity | 圈复杂度用来评估函数的复杂度,如果函数圈复杂度过高,表明函数有太多的决策变量,逻辑拆分不够,难以理解和维护 |
超大类占比 | 超大类数量/代码总量 | 超大类处理太多业务,职责不单一,业务耦合严重,不利于扩展和维护 |
超大函数占比 | 超大函数数量/代码总量 | 同上 |
重复代码频率 | 重复代码段发生次数 | 重复代码会让相同逻辑散落在不同的代码中,维护困难,容易产生修改过程中漏掉一部分导致问题 |
循环访问进程外组件频率 | 在循环中调用数据库或三方系统 API 的次数 | 循环访问进程外组件会引发性能问题,无端占用资源 |
测试覆盖率 | 测试覆盖率 | 测试覆盖率不足,缺少对既有代码的保护,修改很难保证不影响之前的功能 |
组件设计相关指标
在组件自身设计上,也要遵循开发团队约定的设计原则,比如分层架构每层的职责,以及层与层之间的关系。组件设计指标关注组件内部结构设计的合理性,以及一些交互机制的合理性,常用的指标如下:
指标 | 计算方法 | 指标说明 |
---|---|---|
循环依赖数量 | 类之间循环依赖次数 | 循环依赖打破了单向依赖原则,很难判断修改产生的影响。一旦出问题,非常难定位问题 |
枢纽类数量 | 被依赖次数过多的类数量 | 业务实现耦合严重,职责不清 |
依赖异常数量 | 进程内模块分层依赖关系错误的次数 | 同循环依赖 |
组件间重复代码频率 | 公共功能代码重复发生次数 | 对于一些公共功能,没有抽象组件,复制粘贴代码,维护难度大 |
架构设计相关指标
架构设计相关指标关注组件之间的边界,交互关系的规范性,常见指标如下:
指标 | 计算方法 | 指标说明 |
---|---|---|
组件循环依赖数量 | 组件之间循环依赖次数 | 组件间依赖关系混乱,职责不清 |
组件职责偏差率 | 组件职责与业务建模结果之间的偏差率 | 组件没有按业务合理划分,导致组件间关系复杂 |
调用链长度 | 接口在多个组件间流转的次数 | 调用链越长,组件间依赖深度越大,依赖关系越复杂,排查问题越难 |
基础设施(运行时)相关指标 | ||
基础设施(运行时)相关指标从软件系统的运行时观测软件架构的健康度,从外在表现上找到系统的脆弱点,常见指标如下: |
指标 | 计算方法 | 指标说明 |
---|---|---|
基础设施负载率 | 基础设施资源,数据库,缓存的使用量 | 衡量当前系统是否到了瓶颈,能否应对突发的峰值请求 |
平均响应时间 | 生产环境 API 的平均响应时间 | 衡量软件架构的性能 |
系统可用性 | 系统在线可用的时间占比 | 衡量架构的稳定性和整体质量 |
平均故障恢复时长 | 故障发生后恢复可用的平均时长 | 衡量架构在应对突发问题时快速恢复的能力 |
数据不一致问题占比 | 数据不一致问题占所有问题的比例 | 数据不一致通常是因为架构设计不合理,或组件交互方式不合理导致的 |
无用功能占比 | 生产环境长期不使用功能的占比 | API 或者某些功能长期不使用需要尽快清理,降低认知负载,也有助于优化组件之间的关系 |