系统可维护到底指的是什么
June 01, 2020
引言:可维护性是主观的还是客观的?
在大型业务开发中,经常听到这样的声音:“系统维护不下去了,代码复杂度太高了!”
但有趣的是,后台业务很少有类似抱怨,尽管它们的复杂度也不低。这让我开始思考:可维护性到底是主观感受还是客观标准?
考虑以下几个常见场景:
- 接手他人项目:新人觉得前任代码不可维护,要重构;但前任开发者当时并无此感
- 框架认知差异:一线开发同学说 React 项目复杂难维护,但能力强的同学觉得挺好
- 人员变动影响:架构师离职后,新团队成员觉得之前的设计难以理解
- 业务方向变化:多业态支持或业务转向时,原系统复用困难
这些场景说明:可维护性不完全是客观的,它与人、时间、上下文密切相关。
可维护性的四个维度
通过分析上述场景,我将影响可维护性的因素归纳为四个维度:
维度类型 | 客观因素 | 主观因素 |
---|---|---|
系统层面 | 业务复杂度 (商业逻辑的客观复杂性) |
代码与架构 (设计质量的主观评价) |
人员层面 | 技能水平 (拥有一定深度和广度) |
熟悉程度 (时间+意愿)×理解力÷频次 |
维度分析
- 业务复杂度:无法改变的客观事实,来源于商业需求
- 代码与架构:可以优化的技术实现,体现工程能力
- 技能水平:团队成员的技术能力,可通过培养提升
- 熟悉程度:对系统的了解程度,需要时间和精力投入
案例分析:优选项目的维护困境
以优选项目为例,分析其”难以维护”的根本原因:
问题诊断
-
熟悉程度低
- 为赶排期,频繁协调人员支援开发
- 团队对项目平均熟悉度偏低
-
架构不合理
- 每周2大迭代+3小迭代的高频发布
- 忙于排查线上问题,缺乏技术设计时间
-
业务复杂度高
- 团长、用户、新人、老客等多角色
- 促销、活动等多业务场景聚集
-
技能投入不足
- 低职级同学主力开发
- 高职级同学事务性工作多,技术投入少
负向循环
这四个问题相互影响,形成恶性循环:
.png)
负向循环链路: 业务复杂 → 开发压力大 → 设计时间不足 → 架构质量下降 → 维护成本上升 → 熟悉程度要求更高 → 开发效率降低 → 业务压力更大
提升可维护性的系统性方法
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 修复的影响范围
- 新功能的开发效率
持续改进循环
建立正向循环: 合理架构 → 开发效率提升 → 更多设计时间 → 质量持续优化 → 维护成本降低 → 团队满意度提升 → 人才稳定性增强
总结与思考
核心观点
- 可维护性是多维度的:不仅仅是代码质量,还涉及人员、流程、业务等因素
- 客观标准与主观感受并重:既要有可量化的指标,也要关注开发者体验
- 系统性解决方案:四个维度需要协同优化,而非单点突破
实践建议
- 建立度量体系:用数据说话,避免纯主观判断
- 注重人的因素:技能培养和团队稳定性同样重要
- 渐进式改进:避免大规模重构,通过持续优化提升质量
- 业务理解优先:深入理解业务是做好架构设计的前提
最终目标
在业务复杂度不可避免增长的前提下,通过合理的技术手段和管理方式,让系统的可维护性与业务价值保持正相关,实现技术与业务的良性循环。
相关阅读:
参考资料:
Written by xi ming You should follow him on Github