| name | code-refactor |
| description | 基于 Martin Fowler 方法论的系统化代码重构。当用户要求重构代码、改善代码结构、减少技术债务、清理遗留代码、消除代码异味或提升可维护性时使用。本技能引导完成研究、规划和安全增量实现的分阶段流程。 |
Code Refactoring(代码重构)技能
基于 Martin Fowler 的《重构:改善既有代码的设计》(第2版)的系统化重构方法。本技能强调安全的、有测试保障的增量式变更。
"重构是在不改变代码外部行为的前提下,改进其内部结构的过程。" -- Martin Fowler
核心原则
- 行为保持不变:外部行为必须保持不变
- 小步前进:每次做微小的、可测试的变更
- 测试驱动:测试是安全保障网
- 持续进行:重构是持续性的工作,不是一次性事件
- 协作决策:每个阶段都需要用户确认
工作流程概览
第一阶段:调研与分析
↓
第二阶段:测试覆盖率评估
↓
第三阶段:代码异味识别
↓
第四阶段:重构计划制定
↓
第五阶段:增量实施
↓
第六阶段:审查与迭代
第一阶段:调研与分析
目标
- 理解代码库结构和用途
- 确定重构范围
- 收集业务需求上下文
需要向用户确认的问题
开始前,请明确:
- 范围:哪些文件/模块/函数需要重构?
- 目标:你想解决什么问题?(可读性、性能、可维护性)
- 约束:有哪些区域不应该改动?
- 时间压力:是否阻塞其他工作?
- 测试状态:是否有现有测试?是否通过?
操作步骤
输出
向用户展示:
- 代码结构摘要
- 已识别的问题区域
- 初步建议
- 请求批准继续
第二阶段:测试覆盖率评估
为什么测试很重要
"没有测试的重构就像不系安全带开车。" -- Martin Fowler
测试是安全重构的关键使能器。没有测试,你面临引入 Bug 的风险。
评估步骤
-
检查是否有现有测试
find . -name "*test*" -o -name "*spec*" | head -20
-
运行现有测试
npm test
pytest -v
mvn test
-
检查覆盖率(如果可用)
npm run test:coverage
pytest --cov=.
决策点:询问用户
如果有测试且通过:
如果测试缺失或不完整:
提供选项:
- 先写测试(推荐)
- 重构过程中逐步添加测试
- 无测试继续(有风险----需要用户明确确认)
如果测试失败:
- 停止。先修复失败的测试
- 询问用户:我们应该先修复测试吗?
第三阶段:代码异味识别
什么是代码异味?
更深层次问题的症状。它们不是 Bug,但表明代码可以改进。
常见代码异味速查表
详见 references/code-smells.md 获取完整目录。
快速参考
| 异味 | 表征 | 影响 |
|---|
| 过长方法 | 方法超过 30-50 行 | 难以理解、测试和维护 |
| 重复代码 | 相同逻辑出现在多处 | Bug 修复需要在多处进行 |
| 过大类 | 类承担了过多职责 | 违反单一职责原则 |
| 特性依恋 | 方法过度使用另一个类的数据 | 封装不良 |
| 基本类型偏执 | 过度使用基本类型而非对象 | 缺少领域概念 |
| 过长参数列表 | 方法参数超过 4 个 | 难以正确调用 |
| 数据泥团 | 相同数据项总是成组出现 | 缺少抽象 |
| Switch 语句 | 复杂的 switch/if-else 链 | 难以扩展 |
| ** speculative Generality** | "以防万一"的代码 | 不必要的复杂性 |
| 死代码 | 未使用的代码 | 困惑和维护负担 |
输出:异味报告
向用户展示:
- 已识别的异味列表及其位置
- 每个异味的严重程度评估
- 建议的处理优先级顺序
- 请求确认优先级
第四阶段:重构计划制定
选择重构手法
对每个异味,从目录中选择合适的重构技术。
详见 references/refactoring-catalog.md 获取完整列表。
异味到重构手法的映射
| 代码异味 | 推荐的重构手法 |
|---|
| 过长方法 | 提取方法、以查询取代临时变量 |
| 重复代码 | 提取方法、上移方法、形成模板方法 |
| 过大类 | 提取类、提取子类 |
| 特性依恋 | 移动方法、移动字段 |
| 基本类型偏执 | 以对象取代基本值、以类取代类型码 |
| 过长参数列表 | 引入参数对象、保持对象完整 |
| 数据泥团 | 提取类、引入参数对象 |
| Switch 语句 | 以多态取代条件表达式 |
| 投机性泛化 | 折叠继承体系、内联类、移除死代码 |
| 死代码 | 移除死代码 |
分阶段方法
重要:采用分阶段的渐进方式引入重构。
A 阶段:快速见效(低风险、高价值)
- 为清晰起见重命名变量
- 提取明显的重复代码
- 移除死代码
B 阶段:结构性改进(中等风险)
- 从长函数中提取方法
- 引入参数对象
- 将方法移到合适的类中
C 阶段:架构变更(较高风险)
第五阶段:增量实施
黄金法则
"修改 → 测试 → 通过?→ 提交 → 下一步"
实施节奏
对每个重构步骤:
-
预检
-
做一个小改动
-
验证
-
如果测试通过(绿色)
-
如果测试失败(红色)
- 立即停止
- 撤销变更
- 分析出错原因
- 不确定时询问用户
提交策略
每次提交应该是:
- 原子性:一个逻辑上的变更
- 可回退:容易撤销
- 描述性:清晰的提交消息
提交消息示例:
refactor: 从 processOrder() 中提取 calculateTotal()
refactor: 将 'x' 重命名为 'customerCount' 以提高清晰度
refactor: 移除未使用的 validateOldFormat() 方法
第六阶段:审查与迭代
重构后检查清单
重要指南
何时停止并咨询用户
遇到以下情况时始终暂停并征求用户意见:
- 不确定业务逻辑
- 变更可能影响外部 API
- 测试覆盖率不足
- 需要做重大架构决策
- 风险等级上升
- 遇到意外复杂性
安全规则
- 永远不要在没有测试的情况下重构(除非用户明确承认风险)
- 永远不要做大的变更----拆分为微小步骤
- 永远不要跳过变更后的测试运行
- 永远不要在测试失败时继续----先修复或回滚
- 永远不要假设----不确定就问
版本历史
- v1.0.0 (2025-01-15): 初始版本,包含 Fowler 方法论、分阶段流程、用户确认节点