refactoring.md 7.5 KB

重构建议

输入要求

  1. 代码片段(必填):需要重构的代码
  2. 重构目标(可选):如"提高可读性"、"降低复杂度"、"便于测试"
  3. 约束条件(可选):如"不能改变接口"、"保持向后兼容"

执行流程

第一步:Spec范围确认

重构前确认spec范围:

  • 如有spec:确认重构是否影响spec中的scenario,确保重构后scenario仍然通过
  • 变更范围:明确重构影响哪些spec requirement,是否需要更新spec

    ✓ Spec范围确认:
    - 影响Scenario: [scenario列表]
    - 是否需要更新spec: [是/否]
    - 重构后验收标准: [标准]
    

方向语义建模门禁(图/状态机重构强制)

对图遍历、环检测、状态机、依赖解析类代码的重构,强制先建方向语义模型再动码:

  • 方向三要素:节点、边方向(有向/无向/双向)、遍历方向(down/up/both)。重构前显式写明三者,确认遍历方向与边有向性已解耦。
  • 不变量声明:列出重构前后必须保持不变的不变量(如"环数不变""遍历方向与边方向一致""不重复覆盖平行边")。
  • 等价证明:用具体小图(0 节点、自环、两节点互环、菱形 DAG、平行边)说明重构前后结果一致,作为验收基线。
  • 未建立方向语义模型前,不得重写遍历/迁移逻辑;否则一律按"盲目改动"回退。

详见 test-generation.md 算法边界用例清单与 code-review.md 算法正确性审查清单。

第二步:识别坏味道

| 坏味道 | 特征 | 重构手法 | | - | - | - | | 过长函数 | 函数超过50行 | 提取函数 | | 过大类 | 类承担过多职责 | 提取类 | | 重复代码 | 相同/相似代码出现多次 | 提取公共函数 | | 过长参数列表 | 参数超过4个 | 引入参数对象 | | 发散式变化 | 一个类因多种原因修改 | 拆分职责 | | 霰弹式修改 | 修改一处需要改多个类 | 搬移函数/内联 | | 特性依恋 | 函数频繁访问其他类数据 | 搬移函数 | | 数据泥团 | 多处出现相同数据组合 | 提取对象 | | Switch语句 | 大量条件分支 | 多态替代 | | 临时字段 | 对象某些字段只在特定场景使用 | 提取类 | | 过度设计 | 抽象类/接口/配置对象做简单计算 | 直接删除,回归简单 | | 推测性抽象 | 为"未来可能"的需求做的抽象 | 删除,需要时再创建 |

第三步:评估重构价值(Simplicity First优先)

对每个识别出的坏味道:

  • 影响范围:影响多少代码/模块
  • 修复成本:重构所需工作量
  • 收益:可读性、可维护性、可测试性提升
  • 风险:是否可能引入Bug

Karpathy优先级规则:

  1. 简化优先:删除过度设计和推测性抽象的收益 > 重组代码结构
  2. 删除 > 重组:对于过度设计,直接删除回归简单,比重构成"更好的设计"优先级更高
  3. 评估标准:重构后代码行数应该减少或持平,不应显著增加

第四步:制定重构计划

按优先级排序:

  1. 高收益低风险的优先执行
  2. 提供Before/After代码对比
  3. 说明每一步重构的具体操作
  4. 简洁优先(Karpathy原则):重构后的代码应比原来更简单

第五步:生成重构后代码

  • 提供完整的重构后代码
  • 确保代码功能不变
  • 说明重构后的改进点
  • 精准修改(Karpathy原则):每次只做一个重构,不混合多种变更

第六步:验证

  • 检查重构是否引入新问题
  • 确认性能影响
  • 确保测试仍然通过

第七步:记录到项目记忆

重构完成后,将关键决策记录到项目记忆(参见 project-memory-management.md):

  • 记录重构决策(Decision Record 模式):为何重构、选用的重构手法
  • 记录新增的编码规范(Convention Capture 模式):如函数长度上限、类职责划分约定
  • 更新项目架构文档,反映重构后的代码结构

输出格式

## 重构分析报告

**分析文件**:[文件名]
**代码行数**:[X行]
**发现坏味道**:[X]个

## 坏味道识别

### 坏味道1:[名称]
**位置**:[函数/类/行号]
**严重程度**:高/中/低
**原代码**:

[代码片段]``` 问题说明:[为什么这是坏味道]

重构方案

方案1:[重构手法名称]

适用坏味道:[坏味道名称] 重构步骤:

  1. [步骤1]
  2. [步骤2]

重构前:


**重构后**:

[代码]```

收益:[具体改进] 风险:[可能的问题]

重构计划

| 优先级 | 坏味道 | 重构手法 | 预估工作量 | | - | - | - | - | | P0 | [名称] | [手法] | [小/中/大] | | P1 | [名称] | [手法] | [小/中/大] |

完整重构后代码

质量标准

  • 重构必须保持功能不变,不能改变原有行为
  • 每个坏味道必须引用Martin Fowler《重构》中的标准名称
  • 重构步骤必须具体到可操作(如"将第10-25行提取为calculateTotal函数")
  • 必须评估重构风险,高风险重构必须提供回滚方案
  • 重构后代码必须通过原始测试用例(如果提供)
  • 不得建议过度设计(如为简单脚本引入复杂架构)
  • Karpathy红线:简化是最高优先级的重构目标。删除过度设计比重组成"更好的设计"优先级更高
  • Karpathy红线:重构后代码行数应减少或持平,不应显著增加

失败回退机制

| 步骤 | 失败条件 | 回退目标 | 最大重试 | 不可恢复时升级路径 | | - | - | - | - | - | | 第一步:Spec范围确认 | 无spec或spec与代码严重偏离 | 基于代码反推预期行为,标注"无spec对照" | 1 | 建议先走 Spec驱动开发 补全spec再重构 | | 第二步:识别坏味道 | 代码量过大,坏味道识别超限 | 按函数/类分批识别,每批输出局部清单 | 0 | 建议缩小重构范围或分模块进行 | | 第三步:评估重构价值(Simplicity First优先) | 坏味道收益与风险难以量化 | 默认按"高收益低风险优先",标注存疑项 | 1 | 输出收益-风险矩阵,由用户决策优先级 | | 第四步:制定重构计划 | 重构步骤依赖关系复杂,无法线性排序 | 按Wave分组,标注并行/串行依赖 | 2 | 输出依赖图,建议拆分为多个独立重构任务 | | 第五步:生成重构后代码 | 重构后代码行数显著增加(违反Karpathy红线) | 退回第三步重新评估,优先"删除>重组" | 2 | 输出两套方案(保守重构 vs 激进简化),由用户选择 | | 第六步:验证 | 原始测试用例缺失,无法回归 | 生成最小回归测试覆盖核心路径 | 1 | 标注"回归覆盖不足",建议先走 测试用例生成 补全基线 | | 第七步:记录到项目记忆 | 项目记忆系统不可用 | 输出Decision Record到本地文件 | 1 | 标注"决策未沉淀",提示用户手动保存 |

关联 reference

  • karpathy-coding-guidelines(Karpathy编码规范)— 重构后可用 karpathy-coding-guidelines 检查是否过度设计
  • code-review(代码审查)— 重构前可用 code-review 全面评估代码问题
  • test-generation(测试用例生成)— 重构前可用 test-generation 生成基线测试保障安全
  • code-generation(代码生成)— 复杂重构可用 code-generation 生成替代实现
  • project-memory-management(项目记忆管理)— 记录重构决策、新增编码规范并更新架构文档