# 重构建议 ## 输入要求 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. 说明每一步重构的具体操作 - **简洁优先**(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**(项目记忆管理)— 记录重构决策、新增编码规范并更新架构文档