refactoring

Installation
SKILL.md

大规模重构(Refactoring)

重构最大的风险不是改错,而是改了不知道影响了什么。 本 skill 的核心:先建安全网,再动刀子,每一步都有回退点。


第一步:判断是否需要本 skill

收到重构请求
  ├─ 改动 ≤2 个文件,不涉及公共接口?
  │   └─ 直接动手,不需要本 skill
  ├─ 改动 3-5 个文件,局部重构?
  │   └─ 走简化流程:第二步(快速版)→ 第四步 → 第五步
  └─ 涉及公共接口 / 跨模块 / 架构调整 / 数据结构变更?
      └─ 走完整流程:第二步 → 第三步 → 第四步 → 第五步 → 第六步

判断信号

信号 走完整流程
改公共函数/类的签名
拆分或合并模块
改数据模型/数据库 schema
改目录结构
改导入路径被多处引用
纯内部实现优化,接口不变 否,简化流程

第二步:影响分析

动手之前,先搞清楚"改这里会动到哪里"。

2.1 确定重构范围

  • 重构目标:要改什么?改完应该是什么样?(用 AskUserQuestion 和用户对齐)
  • 触发原因:为什么要重构?(技术债 / 性能 / 可维护性 / 新需求倒逼)
  • 不改什么:明确哪些相关代码这次不动(防止 scope 膨胀)

2.2 依赖关系梳理

对要重构的模块,梳理上下游依赖:

被谁调用(上游)→ [重构目标] → 调用了谁(下游)

具体操作

  1. Grep 搜索:搜索要重构的函数名/类名/模块路径,找到所有引用位置
  2. 导入分析:检查 import/require 关系,画出依赖图
  3. 数据流追踪:如果涉及数据结构变更,追踪数据从哪来、到哪去

2.3 影响面评估

列出影响清单:

## 影响分析

### 直接影响(必须改)
- `src/services/auth.ts` — 调用了要重构的函数
- `src/api/user.ts` — 引用了要修改的类型

### 间接影响(需要验证)
- `src/pages/login.tsx` — 依赖 auth 服务,接口不变则不受影响
- `tests/auth.test.ts` — 测试用例需要同步更新

### 不受影响(确认安全)
- `src/utils/format.ts` — 无依赖关系

快速版(局部重构):只做 Grep 搜索确认引用范围,不需要完整的影响清单文档。


第三步:安全网搭建

没有安全网的重构是赌博。安全网 = 测试 + 回退能力。

3.1 确认现有测试覆盖

检查要重构的模块是否有测试:

# 找到相关测试文件
grep -r "重构目标函数名/模块名" tests/ __tests__/ *.test.* *.spec.*
现有测试情况 策略
有测试且覆盖核心路径 先跑通现有测试,确认 baseline 全绿
有测试但覆盖不足 补充关键路径测试后再开始重构
没有测试 必须先补测试,至少覆盖核心路径和边界情况

3.2 补充缺失测试

对于没有测试或覆盖不足的情况:

  • 不需要追求 100% 覆盖率
  • 重点覆盖:要改的函数的核心输入输出公共接口的契约边界情况
  • 测试应该验证行为(输入→输出),不验证实现细节
  • 把测试用例记录到 docs/tests/<模块名>-refactor.md

3.3 创建回退点

# 在重构开始前创建一个明确的 commit 或 branch
git checkout -b refactor/<模块名>
git commit -m "chore: 重构前基线 — 测试全绿"

确保随时可以 git diff refactor/<模块名> 看到所有改动,出问题能快速回退。


第四步:分步重构

大象要一口一口吃。每一步都是可验证的、可回退的。

4.1 制定重构计划

将重构拆分为独立的、可验证的小步骤,每步完成后测试应该通过:

## 重构计划

- [ ] Step 1: <描述> — 预期:测试全绿,行为不变
- [ ] Step 2: <描述> — 预期:测试全绿,行为不变
- [ ] Step 3: <描述> — 预期:测试全绿,新接口生效
- [ ] Step 4: 清理旧代码 — 预期:测试全绿,无废弃代码

拆分原则

  • 每步只做一件事(改结构不改逻辑 / 改逻辑不改结构)
  • 每步改完都能编译通过、测试通过
  • 步骤间尽量不互相依赖
  • 危险操作(删代码、改数据结构)放后面,确认安全了再做

4.2 常用重构策略

场景 推荐策略
改公共接口签名 先新后删:新接口 → 迁移调用方 → 删旧接口
拆分大文件/大函数 提取 → 内联引用 → 验证 → 删旧
改目录结构 先移文件 → 修导入 → 验证 → 提交(单独一步,不混逻辑改动)
替换依赖/框架 适配器模式:新旧共存 → 逐步迁移 → 移除旧依赖
改数据模型 双写过渡:新旧字段并存 → 迁移读写逻辑 → 清理旧字段

4.3 执行纪律

每完成一个步骤:

  1. 跑测试:确认现有测试全部通过
  2. 跑 lint:确认没有引入格式问题
  3. 快速 review:看一眼 diff,确认只改了该改的
  4. 提交:每步一个 commit,message 说清楚做了什么
git commit -m "refactor(auth): step 1 — 提取 token 验证为独立函数"

如果某一步测试挂了

  • 先看是不是测试本身需要更新(因为接口变了)
  • 如果是意料之外的挂掉 → 停下来分析,不要硬继续
  • 实在搞不清 → 回退到上一步的 commit,重新想策略

第五步:回归验证

重构的目标是"行为不变,结构更好"。验证行为是否真的没变。

5.1 运行全量测试

# 项目测试
npm test  # 或 pytest

# 如果有 e2e 测试
npm run test:e2e

5.2 人工验证核心路径

测试不能覆盖一切。对于以下场景,手动验证:

  • 页面渲染是否正常(前端重构)
  • API 响应是否符合预期(后端重构)
  • 关键业务流程走通(端到端)

5.3 对比验证

# 对比重构前后的 git diff,确认改动范围符合预期
git diff refactor/<模块名>..HEAD --stat

检查:

  • 没有混入不相关的改动
  • 没有遗留 debug 代码
  • 没有遗留注释掉的旧代码

第六步:收尾

6.1 清理

  • 删除废弃的旧代码(不是注释掉,是删掉)
  • 更新相关文档(如果重构改了目录结构、接口、配置等)
  • 更新 docs/tests/ 中的测试用例(重构过程中新增的测试要沉淀)

6.2 交给 task-finish 进行 CR 自检

重构完成后,交给 task-finish 执行深度自检:

  • 改动范围是否符合重构目标?
  • 有无混入不相关变更?
  • 有无遗留调试代码?

6.3 复盘沉淀(由 task-manager 触发)

重构完成后,当用户将需求标 done 时,由 task-manager 触发复盘。重构类任务建议做完整复盘,记录到 docs/decisions/

  • 重构的动机和目标达成了吗?
  • 哪些步骤顺利?哪些卡住了?
  • 影响分析是否准确?遗漏了什么?
  • 下次类似重构有什么经验可复用?

与其他 skill 的衔接

task-start
  │ 判定为重构任务
refactoring(本 skill)
  ├─ 第二步 ← dependency-map(影响分析,如果有的话)
  ├─ 第二步 ← writing(写重构方案,大型重构时)
  ├─ 第四步 ← task-execute(跨会话进度管理)
  ├─ 第五步 ← perf-profiling(性能相关重构时对比前后)
  ├─ 收尾 → task-finish(CR 自检)
  └─ 需求标 done → task-manager → 触发复盘

反模式清单

反模式 后果 正确做法
没有安全网就开始改 改完不知道哪里坏了 先确认测试覆盖,再动手
一次改太多 出问题无法定位 小步提交,每步可验证
重构时顺手加功能 scope 膨胀,风险叠加 重构和功能开发分开做
改结构的同时改逻辑 无法区分是结构改动还是逻辑改动引起的问题 一步只做一件事
注释掉旧代码不删 代码越来越脏 确认不用了就删
跳过回归测试 上线后才发现问题 每步跑测试,最后全量回归
不记录影响面 下次改同样的地方又不知道影响谁 影响分析写下来
Related skills
Installs
2
GitHub Stars
102
First Seen
Apr 9, 2026