mcpskills.net
技能MCP智能体提示词
mcpskills.net — A curated directory of AI agent Skills and MCP servers
TermsPrivacy
← 返回技能
Development

弃用与迁移

管理弃用和迁移。适用于移除旧系统、API 或功能,或将用户从一个实现迁移到另一个实现时。

作者:Addy Osmani仓库 →来源 →

代码是负债,而非资产。每一行代码都有持续的维护成本。

使用场景

  • 用新系统替换旧系统、API 或库
  • 淘汰不再需要的功能
  • 合并重复实现
  • 移除无人拥有但人人依赖的死代码
  • 规划新系统的生命周期

核心原则

代码是负债

每一行代码都有持续成本:测试、文档、安全补丁、依赖更新和心智负担。当同样的功能可以用更少的代码实现时——旧代码就应该被移除。

Hyrum 定律使移除变得困难

当用户足够多时,每一个可观察到的行为都会被依赖——包括 Bug、时序特性和未记录的副作用。弃用需要主动迁移,而不仅仅是发布公告。

弃用规划从设计时开始

构建新功能时,问自己:"三年后我们如何移除它?"

弃用决策

在弃用任何东西之前,回答这些问题:

1. 这个系统是否仍然提供独特的价值?
   → 如果是,维护它。如果否,继续。

2. 有多少用户/消费者依赖它?
   → 量化迁移范围。

3. 是否有替代方案?
   → 如果没有,先构建替代方案。不要在没有替代方案的情况下弃用。

4. 每个消费者的迁移成本是多少?
   → 如果可以自动完成,就自动完成。如果是手动且成本高,与维护成本权衡。

5. 不弃用的持续维护成本是什么?
   → 安全风险、工程师时间、复杂性的机会成本。

强制弃用与建议弃用

| 类型 | 使用场景 | 机制 | |------|----------|------| | 建议弃用 | 迁移可选,旧系统稳定 | 警告、文档、提示 | | 强制弃用 | 旧系统有安全问题、阻碍进展 | 设定硬性截止日期并提供迁移工具 |

默认使用建议弃用。 仅在维护成本或风险证明强制迁移合理时才使用强制弃用。

迁移流程

第 1 步:构建替代方案

不要在没有可用替代方案的情况下弃用。替代方案必须:

  • 覆盖旧系统的所有关键用例
  • 有文档和迁移指南
  • 在生产环境中得到验证

第 2 步:发布公告并编写文档

## 弃用通知:OldService

**状态:** 自 2025-03-01 起弃用
**替代方案:** NewService(参见下方迁移指南)
**移除日期:** 建议性——暂无硬性截止日期
**原因:** OldService 需要手动扩展且缺乏可观测性。

### 迁移指南
1. 将 `import { client } from 'old-service'` 替换为 `import { client } from 'new-service'`
2. 更新配置(参见下方示例)
3. 运行迁移验证脚本:`npx migrate-check`

第 3 步:逐步迁移

逐个迁移消费者,而非一次性全部迁移:

1. 识别与弃用系统的所有接触点
2. 更新为使用替代方案
3. 验证行为一致(测试、集成检查)
4. 移除对旧系统的引用
5. 确认无回归

第 4 步:移除旧系统

只有在所有消费者都迁移后:

1. 验证零活跃使用(指标、日志、依赖分析)
2. 移除代码
3. 移除相关测试、文档和配置
4. 移除弃用通知
5. 庆祝——移除代码是一项成就

迁移模式

绞杀者模式

新旧系统并行运行,逐步将流量从旧系统路由到新系统。

阶段 1:新系统处理 0%,旧系统处理 100%
阶段 2:新系统处理 10%(金丝雀发布)
阶段 3:新系统处理 50%
阶段 4:新系统处理 100%,旧系统空闲
阶段 5:移除旧系统

适配器模式

创建一个适配器,将旧接口的调用转换为新实现。

class LegacyTaskService implements OldTaskAPI {
  constructor(private newService: NewTaskService) {}

  getTask(id: number): OldTask {
    const task = this.newService.findById(String(id));
    return this.toOldFormat(task);
  }
}

功能标志迁移

使用功能标志将消费者从旧系统切换到新系统:

function getTaskService(userId: string): TaskService {
  if (featureFlags.isEnabled('new-task-service', { userId })) {
    return new NewTaskService();
  }
  return new LegacyTaskService();
}

僵尸代码

僵尸代码是无人拥有但人人依赖的代码。特征:

  • 超过 6 个月没有提交但仍有活跃消费者
  • 没有指定的维护者或团队
  • 失败的测试无人修复
  • 有已知漏洞的依赖无人更新

应对措施: 要么指定负责人并妥善维护,要么制定具体的迁移计划后弃用。

验证

完成弃用后:

  • [ ] 替代方案已在生产中验证,覆盖所有关键用例
  • [ ] 迁移指南存在,包含具体步骤和示例
  • [ ] 所有活跃消费者已迁移(通过指标/日志验证)
  • [ ] 旧代码、测试、文档和配置已完全移除
  • [ ] 代码库中无对已弃用系统的引用
  • [ ] 弃用通知已移除