---
title: 系统可维护到底指的是什么
date: "2020-06-01 23:00"
tags: ["架构"]
published: true
---

## 可维护性的判断条件

在大型业务开发中，团队常用“难以维护”描述代码复杂、修改成本高的系统。后台业务同样可能具有较高复杂度，却未必产生相同的维护感受，因此需要区分可观察的质量指标和团队的实际理解成本。

以下场景会产生不同的维护成本：

1. **接手他人项目**：新人觉得前任代码不可维护，要重构；但前任开发者当时并无此感
2. **框架认知差异**：一线开发同学说 React 项目复杂难维护，但能力强的同学觉得挺好
3. **人员变动影响**：架构师离职后，新团队成员觉得之前的设计难以理解
4. **业务方向变化**：多业态支持或业务转向时，原系统复用困难

这些场景表明，可维护性同时受系统实现、团队成员、业务变化和交接上下文影响。

## 可维护性的四个维度

本文按四个维度整理影响可维护性的因素：

| 维度类型     | 客观因素                                | 主观因素                               |
| ------------ | --------------------------------------- | -------------------------------------- |
| **系统层面** | 业务复杂度<br/>（商业逻辑的客观复杂性） | 代码与架构<br/>（设计质量的主观评价）  |
| **人员层面** | 技能水平<br/>（拥有一定深度和广度）     | 熟悉程度<br/>（时间+意愿）×理解力÷频次 |

### 四类因素

- **业务复杂度**：由商业需求带来的约束。
- **代码与架构**：可以调整的技术实现。
- **技能水平**：团队成员处理相关技术问题的能力。
- **熟悉程度**：团队理解系统所投入的时间和精力。

## 优选项目中的维护问题

以优选项目为例，以下因素共同提高了修改和排查成本：

### 影响因素

1. **熟悉程度低**

   - 为赶排期，频繁协调人员支援开发
   - 团队对项目平均熟悉度偏低

2. **架构不合理**

   - 每周2大迭代+3小迭代的高频发布
   - 忙于排查线上问题，缺乏技术设计时间

3. **业务复杂度高**

   - 团长、用户、新人、老客等多角色
   - 促销、活动等多业务场景聚集

4. **技能投入不足**
   - 低职级同学主力开发
   - 高职级同学事务性工作多，技术投入少

### 相互影响的过程

这四类问题会相互放大：

![image (3)](../../assets/2020/06-01-系统可维护到底指的是什么/image-3.png)

业务复杂度提高后，开发压力会压缩设计时间；架构质量下降会增加维护成本，并提高熟悉系统所需的时间，进而降低开发效率。

## 分维度改善可维护性

### 1. 业务复杂度：拆分与抽象

业务复杂度不能通过代码消除，只能通过模块划分和抽象控制其传播范围。

#### 理论基础

业务复杂度是客观存在的，系统架构设计的作用是：

- **降低理解范围**：让单次修改只涉及有限的业务规则。
- **增加系统实体数量**：通过抽象层分离不同职责。

抽象层会增加系统实体数量，但可以减少单个开发者在一次修改中必须理解的业务范围。

#### 实践方法

- **业务领域拆分**：按业务边界划分模块
- **分层架构设计**：容器层、基础能力层、业务能力层
- **确定最小知识集**：每个模块只需了解必要的依赖

### 2. 代码与架构：可衡量的质量标准

#### 架构设计原则

架构应按业务约束划分技术实现，并明确模块间的职责和接口。

- **适应度函数**：架构设计应反映业务的实际复杂度。
- **降低认知负担**：隐藏当前修改不需要理解的实现细节。
- **明确模块边界**：定义模块职责和接口。

![85dc12757fc22f7cccssa1dg](../../assets/2020/06-01-系统可维护到底指的是什么/85dc12757fc22f7cccssa1dg.png)

#### 可维护性度量标准

可维护性度量需要随功能变化反映实际变更成本，可将这一目标抽象为适应度函数 `Maintainable = Fi(Feature)`。

**评估条件**：

1. **限制修改放大**（Change Amplification）：小改动不应引起大范围修改。
2. **控制认知负担**（Cognitive Load）：开发者理解一次修改所需的信息应有限。
3. **暴露依赖关系**（Unknown Unknown）：避免依赖关系只在变更时才被发现。

#### 具体度量指标

**源码层面**：

1. **LLOC（Logical Lines of Code）**

   ```javascript
   // LOC 1, LLOC 2 - 不稳定
   if (true) console.log("hello")

   // LOC 3, LLOC 2 - 更稳定
   if (true) {
     console.log("hello")
   }
   ```

2. **Halstead Complexity (HV)**

   - 基于操作符和操作数的复杂度计算
   - 参考：[Halstead Complexity Measures](https://github.com/aametwally/Halstead-Complexity-Measures)

3. **认知复杂度（Cognitive Complexity）**
   ```javascript
   a && b // 圈复杂度：2，认知复杂度：2
   a && b && c && d // 圈复杂度：4，认知复杂度：2
   a || (b && c) || d // 圈复杂度：4，认知复杂度：4
   ```

**架构层面** [什么是耦合(共生)，什么是内聚](.//05-30-什么是耦合(共生)，什么是内聚.md)：

- **内聚性**：模块内部的相关性
- **耦合度**：模块间的依赖程度

**综合指标**：

**可维护性指数（Maintainability Index）**

- 由 Paul Oman 和 Jack Hagemeister 在1992年提出
- 综合 HV、CC、LLOC 三个指标
- 有多个工具版本：SEI、Visual Studio、Radon 等

### 3. 熟悉程度：流程与规范保障

#### 实施措施

- **主 R 锁定制**：减少核心开发人员变动。
- **降低迭代频次**：预留熟悉系统和设计方案的时间。
- **技术方案评审**：提高设计审查要求。
- **文档**：维护代码注释、架构文档和业务文档。

#### 知识传承机制

- **Code Review 制度**：通过审查传播代码约定和架构判断。
- **技术分享**：定期说明架构设计和业务规则。
- **Pair Programming**：新人与熟悉系统的成员结对开发。

### 4. 技能水平：岗位胜任力建设

#### 能力模型

- **技术深度**：框架原理、算法数据结构、系统设计
- **技术广度**：跨端能力、全栈理解、工程化实践
- **业务理解**：领域知识、用户需求、商业逻辑

#### 提升路径

- **选**：招聘匹配岗位要求的人才
- **用**：合理分配任务，人岗匹配
- **育**：技术培训、业务培训和团队经验分享。
- **励**：技术成长激励、业务贡献激励
- **汰**：不适应者调整或淘汰

## 监控与持续改进

### 建立监控体系

1. **代码质量监控**

   - 定期计算 Maintainability Index
   - 跟踪复杂度指标变化趋势
   - 设置质量红线和预警机制

2. **团队能力评估**

   - 定期评估团队技能水平
   - 跟踪项目熟悉程度
   - 收集主观维护感受

3. **业务影响分析**
   - 需求变更的开发成本
   - Bug 修复的影响范围
   - 新功能的开发效率

### 持续改进

架构改进降低维护成本后，可以释放设计和排查时间；后续迭代应将这部分时间用于验证和调整模块边界。

## 结论

可维护性不能仅由代码复杂度判断。变更范围、理解成本、隐藏依赖等源码和架构指标，需要结合团队熟悉程度、技能投入和业务复杂度一起评估。改进时先用度量和实际维护问题定位约束，再以可验证的小范围修改调整架构、流程或人员安排。

---

**相关阅读**：

- [技术债务管理](./05-20-技术债思考.md)
- [复杂性管理框架](../2016/05-11-解决复杂问题.md)
- [代码质量度量标准](https://www.sonarsource.com/docs/CognitiveComplexity.pdf)

**参考资料**：

- [Software Metrics for Predicting Maintainability](http://www.dmi.usherb.ca/~frappier/Papers/tm2.pdf)
- [A Software Metric System for Module Coupling](https://cs.gmu.edu/~offutt/rsrch/papers/mj-coupling.pdf)
- [Using Metrics to Evaluate Software System Maintainability](https://www.ecs.csun.edu/~rlingard/comp589/ColemanPaper.pdf)
