衡量技术债务:超越 SonarQube
Source: Dev.to
SonarQube 的局限性
SonarQube 能告诉你代码异味,但它并不能揭示隐藏的耦合,例如一个计费服务与认证服务共享同一数据库表——这种未记录的关系只有即将离职的某位工程师知道。
这类技术债务才是真正会造成伤害的。
传统代码质量工具衡量的内容
- 循环复杂度(函数层面)
- 代码重复
- 测试覆盖率百分比
- 风格违规
- 已知的漏洞模式
这些指标有用,但比较表面。一个代码库在 SonarQube 上可以拿到 A+,却仍然是运营噩梦,因为真正的债务是结构性的,而不是语法层面的。
结构性债务
常见症状
- 服务之间出现不必要的耦合。
- 本应独立的服务共享数据库表。
- 从未清理的特性开关(feature flag),导致许多代码路径受其控制。
如何衡量结构性债务
- 跨特性依赖计数 – 连接本应独立特性的边的数量。
- 耦合比率 – 每个特性的内部依赖 / 外部依赖。
- 循环依赖检测 – 互相依赖的服务(A → B → A)。
知识债务
症状
- 部落式知识未被文档化(例如,“去找 Mike”)。
- 只有一个人理解的代码区域。
如何衡量知识债务
- 按特性划分的 Bus factor – 最近 6 个月内每个特性有多少人提交过代码。
- 知识集中度 – 每个特性中代码由最高贡献者编写的比例。
- 评审覆盖率 – 每个区域的 PR 中有多少比例是由作者之外的人审阅的。
架构债务
症状
- 本应拆分的单体应用仍然是 monolith。
- 服务边界划分不当。
- 过度打补丁的抽象层,比它们包装的代码更难理解。
如何衡量架构债务
- 变更耦合 – 总是一起变更但属于不同特性的文件(暗示缺失抽象)。
- 按特性划分的 churn 率 – churn 高的特性演进速度快于其架构所能支撑。
- PR 大小分布 – 某特性中持续出现的大 PR 可能表明边界放错。
更具可操作性的仪表盘
与其只看单一的 SonarQube 等级,不如想象一个仪表盘展示:
- 特性健康网格 – 每个特性在复杂度、耦合、知识集中度和 churn 方面的评分。
- 风险热点 – 按 (churn × 耦合 × 单作者 %) 排名前 10 的文件,依据生产事故潜在性排序。
- 知识风险 – 最近提交中 > 80 % 来自同一人的特性。
- 依赖异常 – 最近一个季度内增长的跨特性依赖。
- 演进压力 – churn 高但测试覆盖率低的特性——未来事故最可能的来源。
这些洞察正是 Glue 的 team insights 与 code health 功能提供的:关于真实风险的系统级情报,而不仅仅是语法层面的指标。
将指标转化为决策
- 计费模块知识风险高? → 在该贡献者休假前安排一次配对编程。
- 跨特性耦合在增加? → 优先进行一次重构冲刺,清理边界。
- 认证模块 churn 高且覆盖率低? → 在下一个特性迭代前补上集成测试。
“我们有技术债务”(大家都知道)与“我们有 3 个知识高度集中的特性、2 处耦合异常以及 1 个 churn 高且零测试覆盖的区域”(可操作情报)之间的区别,就是抱怨和真正解决问题的区别。