正在加载,请稍候…

管理技术债务:实现可持续发展的策略

识别、衡量并战略性地偿还技术债务。学习债务追踪、重构冲刺以及如何为偿还债务提供商业理由。

管理技术债务:实现可持续发展的策略

管理技术债务:实现可持续发展的策略

技术债务是选择现在简单的解决方案而非正确解决方案的成本。

技术债务的类型

有意的:“我们知道这很乱,以后会修复”
  - 为赶截止日期而故意走捷径
  - 应记录并安排修复计划

意外的:“我们不知道这会引发问题”
  - 过时的依赖
  - 当时合理但现在不合理的架构

代码腐烂:原本良好的代码随时间退化
  - 代码曾经可用,但周围的世界变了

管理技术债务:实现可持续发展的策略插图

识别债务

// 表明债务的代码坏味道:

// 1. 长函数(超过30行就值得怀疑)
function processEverything(data: any) {
  // 200行混合关注点
}

// 2. 高圈复杂度
function calculatePrice(order: any) {
  if (order.type === 'a') {
    if (order.customer === 'premium') {
      if (order.items.length > 10) {
        // 深度嵌套...
      }
    }
  }
}

// 3. 重复代码(复制粘贴债务)
// 相同的验证逻辑出现在5个不同文件中

// 4. 过时的注释
// TODO: 修复此问题(来自2019年)
// HACK: 绕过库X v1.2的bug(现在已是v5.0)

衡量债务

# 使用plato进行复杂度分析(JavaScript)
npx plato -r -d reports src/

# 代码重复检测
npx jscpd src/ --min-lines 10 --min-tokens 50

# 死代码检测
npx ts-prune

# 依赖版本检查
npx npm-check -u

# 代码覆盖率(低覆盖率=隐藏的债务)
npm run test -- --coverage

债务积压

![管理技术债务:实现可持续发展的策略插图](https://images.pexels.com/photos/13450812/pexels-photo-13450812.jpeg?auto=compress&cs=tinysrgb&h=650&w=940)

## 技术债务积压

### 高优先级(阻碍开发速度)
- [ ] DEBT-001: 将基于回调的数据库层替换为async/await
  - 工作量: 大, 影响: 高
  - 影响: 23个文件,导致70%的异步bug

### 中优先级(造成困扰)
- [ ] DEBT-002: 拆分UserManager上帝类
  - 工作量: 中, 影响: 中
  - 测试覆盖率: 12%

![管理技术债务:实现可持续发展的策略插图](https://images.pexels.com/photos/6805155/pexels-photo-6805155.jpeg?auto=compress&cs=tinysrgb&h=650&w=940)

### 低优先级(小烦恼)
- [ ] DEBT-003: 升级已弃用的webpack插件
  - 工作量: 小, 影响: 低

偿还债务的策略

1. 童子军规则:让代码比你发现时更好
   - 修改文件时,顺手清理小问题
   - 小修复无需单独的“清理PR”

2. 绞杀者模式用于大型重写:
   - 不要一次性重写所有内容
   - 在新代码旁构建,逐步路由流量

3. 专门的债务冲刺(20%容量):
   - 预留冲刺容量用于债务减少
   - 让债务在规划中可见

4. 债务墙:
   - 物理或数字看板,列出所有已知债务
   - 团队投票决定处理哪些

提供商业理由

“这个功能需要3周,因为我们必须在旧支付代码上绕行”
对比
“如果我们花1周清理支付代码,这个功能只需1周,
并且接下来的10个支付功能每个节省1周 = 10倍回报”

将债务表述为:
- 功能开发速度成本:“每个功能多花X周”
- 可靠性成本:“上个月3次事故追溯到模块Y”
- 入职成本:“新开发人员需要2周理解模块Z”

可持续的团队将技术债务视为一等关注点,而不是等到危机才处理。