name: refactoring-code description: 通过测试验证改进代码结构,同时保持行为不变。用于清理代码、减少重复、简化复杂性或重新组织模块。
重构代码
核心原则: 重构改变结构,不改变功能。如果行为改变,那就是重写。
五个阶段
重构进度:
- [ ] 阶段 1:理解当前行为
- [ ] 阶段 2:验证行为驱动测试存在
- [ ] 阶段 3:识别问题
- [ ] 阶段 4:规划增量步骤
- [ ] 阶段 5:执行并持续验证
阶段 1:理解当前行为
- 阅读代码以理解目的,不仅仅是实现
- 使用 Grep 查找所有调用点和消费者
- 记录输入、输出、副作用、边界情况
阶段 2:验证测试覆盖(关键)
测试必须验证行为,而不是实现:
// ✅ 行为驱动 - 在重构中存活
test('当 API 返回 404 时显示错误', async () => {
server.use(http.get('/api/users', () => new HttpResponse(null, { status: 404 })));
render(<UserList />);
expect(await screen.findByText(/未找到/i)).toBeInTheDocument();
});
// ❌ 实现细节 - 在重构中中断
test('设置错误状态', () => {
wrapper.instance().handleError(new Error('404'));
expect(wrapper.state('error')).toBe('404');
});
如果测试缺失: 首先使用 Skill(ce:writing-tests) 添加行为驱动测试。
阶段 3:识别问题
| 问题 | 指标 | 修复 |
|---|---|---|
| 复杂性 | 深层嵌套,>50 行函数 | 提取更小的函数 |
| 重复 | 复制粘贴的代码 | 提取共享工具 |
| 命名差 | x、data、temp |
重命名为意图 |
| 类型缺失 | any 类型,断言 |
添加适当类型 |
阶段 4:规划重构
- 分解为小的、独立可测试的步骤
- 先做高影响 + 低风险(例如,重命名)
- 推迟高风险更改(算法重写)
阶段 5:执行与验证
- 一次做一个更改
- 每次更改后运行测试
- 检查 TypeScript 编译
- 验证行为未改变
如果某些东西中断: 停止。使用 Skill(ce:systematic-debugging)。在理解之前不要继续。
红旗 - 停止并重新评估
- 在重构时改变行为(分离关注点)
- 跳过测试(“就这一次”)
- 增加复杂性以移除复杂性
- “这很聪明!”(清晰度 > 聪明度)
- 在见到模式三次之前进行抽象
快速参考
| 味道 | 重构 |
|---|---|
| 长函数 | 提取更小的函数 |
| 重复代码 | 提取到共享工具 |
| 深层嵌套 | 提前返回,守卫子句 |
| 魔法数字 | 命名常量 |
| 大组件 | 拆分为更小组件 |
| 长参数列表 | 参数对象 |
何时停止
当代码清晰、重复消除、类型明确、测试通过时停止。
不要继续如果:
- 使代码“优雅”但更难理解
- 在出现三次之前进行抽象
- 没有测量就优化
对于 React/TypeScript 模式,参见 references/react-typescript.md。