可维护性的判断条件
在大型业务开发中,团队常用“难以维护”描述代码复杂、修改成本高的系统。后台业务同样可能具有较高复杂度,却未必产生相同的维护感受,因此需要区分可观察的质量指标和团队的实际理解成本。
以下场景会产生不同的维护成本:
- 接手他人项目:新人觉得前任代码不可维护,要重构;但前任开发者当时并无此感
- 框架认知差异:一线开发同学说 React 项目复杂难维护,但能力强的同学觉得挺好
- 人员变动影响:架构师离职后,新团队成员觉得之前的设计难以理解
- 业务方向变化:多业态支持或业务转向时,原系统复用困难
这些场景表明,可维护性同时受系统实现、团队成员、业务变化和交接上下文影响。
可维护性的四个维度
本文按四个维度整理影响可维护性的因素:
| 维度类型 | 客观因素 | 主观因素 |
|---|---|---|
| 系统层面 | 业务复杂度 (商业逻辑的客观复杂性) | 代码与架构 (设计质量的主观评价) |
| 人员层面 | 技能水平 (拥有一定深度和广度) | 熟悉程度 (时间+意愿)×理解力÷频次 |
四类因素
- 业务复杂度:由商业需求带来的约束。
- 代码与架构:可以调整的技术实现。
- 技能水平:团队成员处理相关技术问题的能力。
- 熟悉程度:团队理解系统所投入的时间和精力。
优选项目中的维护问题
以优选项目为例,以下因素共同提高了修改和排查成本:
影响因素
-
熟悉程度低
- 为赶排期,频繁协调人员支援开发
- 团队对项目平均熟悉度偏低
-
架构不合理
- 每周2大迭代+3小迭代的高频发布
- 忙于排查线上问题,缺乏技术设计时间
-
业务复杂度高
- 团长、用户、新人、老客等多角色
- 促销、活动等多业务场景聚集
-
技能投入不足
- 低职级同学主力开发
- 高职级同学事务性工作多,技术投入少
相互影响的过程
这四类问题会相互放大:
业务复杂度提高后,开发压力会压缩设计时间;架构质量下降会增加维护成本,并提高熟悉系统所需的时间,进而降低开发效率。
分维度改善可维护性
1. 业务复杂度:拆分与抽象
业务复杂度不能通过代码消除,只能通过模块划分和抽象控制其传播范围。
理论基础
业务复杂度是客观存在的,系统架构设计的作用是:
- 降低理解范围:让单次修改只涉及有限的业务规则。
- 增加系统实体数量:通过抽象层分离不同职责。
抽象层会增加系统实体数量,但可以减少单个开发者在一次修改中必须理解的业务范围。
实践方法
- 业务领域拆分:按业务边界划分模块
- 分层架构设计:容器层、基础能力层、业务能力层
- 确定最小知识集:每个模块只需了解必要的依赖
2. 代码与架构:可衡量的质量标准
架构设计原则
架构应按业务约束划分技术实现,并明确模块间的职责和接口。
- 适应度函数:架构设计应反映业务的实际复杂度。
- 降低认知负担:隐藏当前修改不需要理解的实现细节。
- 明确模块边界:定义模块职责和接口。
可维护性度量标准
可维护性度量需要随功能变化反映实际变更成本,可将这一目标抽象为适应度函数 Maintainable = Fi(Feature)。
评估条件:
- 限制修改放大(Change Amplification):小改动不应引起大范围修改。
- 控制认知负担(Cognitive Load):开发者理解一次修改所需的信息应有限。
- 暴露依赖关系(Unknown Unknown):避免依赖关系只在变更时才被发现。
具体度量指标
源码层面:
-
LLOC(Logical Lines of Code)
// LOC 1, LLOC 2 - 不稳定 if (true) console.log("hello") // LOC 3, LLOC 2 - 更稳定 if (true) { console.log("hello") } -
Halstead Complexity (HV)
- 基于操作符和操作数的复杂度计算
- 参考:Halstead Complexity Measures
-
认知复杂度(Cognitive Complexity)
a && b // 圈复杂度:2,认知复杂度:2 a && b && c && d // 圈复杂度:4,认知复杂度:2 a || (b && c) || d // 圈复杂度:4,认知复杂度:4
架构层面 什么是耦合(共生),什么是内聚:
- 内聚性:模块内部的相关性
- 耦合度:模块间的依赖程度
综合指标:
可维护性指数(Maintainability Index)
- 由 Paul Oman 和 Jack Hagemeister 在1992年提出
- 综合 HV、CC、LLOC 三个指标
- 有多个工具版本:SEI、Visual Studio、Radon 等
3. 熟悉程度:流程与规范保障
实施措施
- 主 R 锁定制:减少核心开发人员变动。
- 降低迭代频次:预留熟悉系统和设计方案的时间。
- 技术方案评审:提高设计审查要求。
- 文档:维护代码注释、架构文档和业务文档。
知识传承机制
- Code Review 制度:通过审查传播代码约定和架构判断。
- 技术分享:定期说明架构设计和业务规则。
- Pair Programming:新人与熟悉系统的成员结对开发。
4. 技能水平:岗位胜任力建设
能力模型
- 技术深度:框架原理、算法数据结构、系统设计
- 技术广度:跨端能力、全栈理解、工程化实践
- 业务理解:领域知识、用户需求、商业逻辑
提升路径
- 选:招聘匹配岗位要求的人才
- 用:合理分配任务,人岗匹配
- 育:技术培训、业务培训和团队经验分享。
- 励:技术成长激励、业务贡献激励
- 汰:不适应者调整或淘汰
监控与持续改进
建立监控体系
-
代码质量监控
- 定期计算 Maintainability Index
- 跟踪复杂度指标变化趋势
- 设置质量红线和预警机制
-
团队能力评估
- 定期评估团队技能水平
- 跟踪项目熟悉程度
- 收集主观维护感受
-
业务影响分析
- 需求变更的开发成本
- Bug 修复的影响范围
- 新功能的开发效率
持续改进
架构改进降低维护成本后,可以释放设计和排查时间;后续迭代应将这部分时间用于验证和调整模块边界。
结论
可维护性不能仅由代码复杂度判断。变更范围、理解成本、隐藏依赖等源码和架构指标,需要结合团队熟悉程度、技能投入和业务复杂度一起评估。改进时先用度量和实际维护问题定位约束,再以可验证的小范围修改调整架构、流程或人员安排。
相关阅读:
参考资料:
