refactor

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Refactor Skill

重构技能

Quick Ref: Safe, incremental refactoring with test verification at every step. One transformation, one test run, one commit. Never batch.
YOU MUST EXECUTE THIS WORKFLOW. Do not just describe it.
快速参考: 安全的增量重构,每一步都经过测试验证。一次转换、一次测试运行、一次提交。永远不要批量操作。
你必须执行此工作流,不要仅对其进行描述。

Modes

模式

1. Target Mode (default)

1. 目标模式(默认)

/refactor <file-or-function>
Refactor a specific file, function, or class. You identify what needs improving, plan the steps, and execute them one at a time with test verification.
/refactor <file-or-function>
重构指定的文件、函数或类。你需要识别需要优化的内容,规划执行步骤,逐次执行并在每一步完成测试验证。

2. Sweep Mode

2. 扫描模式

/refactor --sweep <scope>
Find and fix complexity hotspots across a directory, package, or entire project. Runs
/complexity
first to identify targets, then works through them in priority order (highest complexity first).
<scope>
can be:
  • A directory path (
    cli/internal/
    )
  • A package name (
    goals
    )
  • all
    (entire project -- use with caution)
/refactor --sweep <scope>
查找并修复整个目录、包或项目中的复杂度热点。首先运行
/complexity
识别重构目标,然后按照优先级顺序处理(复杂度最高的优先)。
<scope>
可选值包括:
  • 目录路径(
    cli/internal/
  • 包名(
    goals
  • all
    (整个项目——请谨慎使用)

3. Extract Mode

3. 提取模式

/refactor --extract <pattern>
Extract method, class, or module from a target. The
<pattern>
describes what to extract:
  • method:<function-name>
    -- extract a section of a long function into a named helper
  • module:<file>
    -- split a god file into focused modules
  • class:<class-name>
    -- extract a class into its own file
/refactor --extract <pattern>
从目标中提取方法、类或模块。
<pattern>
用于描述要提取的内容:
  • method:<function-name>
    ——将长函数中的一段代码提取为命名辅助函数
  • module:<file>
    ——将庞大的单文件拆分为职责聚焦的多个模块
  • class:<class-name>
    ——将类提取到独立文件中

Core Principle

核心原则

Every refactoring step must be verified by running tests before proceeding to the next step.
No batching. No "I'll run tests after all changes." Each transformation is atomic:
Transform -> Test -> Pass? -> Commit -> Next
                       |
                       No -> Revert -> Re-analyze
进入下一个重构步骤之前,当前步骤必须通过运行测试完成验证。
不允许批量操作,不允许“所有变更完成后再统一运行测试”。每一次转换都是原子操作:
Transform -> Test -> Pass? -> Commit -> Next
                       |
                       No -> Revert -> Re-analyze

Execution Steps

执行步骤

Step 0: Pre-flight -- Establish Green Baseline

步骤0:预检查——建立绿色基线

Run the full test suite for the target scope BEFORE making any changes.
Go projects:
bash
cd cli && go test ./...
Python projects:
bash
pytest
If tests fail: STOP. Do not refactor code with a broken test suite. Fix the failing tests first, or scope your refactoring to exclude the broken area.
Record the baseline:
  • Number of passing tests
  • Test execution time
  • Any skipped tests
在进行任何代码变更前,先运行目标范围的完整测试套件。
Go项目:
bash
cd cli && go test ./...
Python项目:
bash
pytest
如果测试失败:立即停止。 不要对测试套件已损坏的代码进行重构。优先修复失败的测试,或者调整重构范围排除故障区域。
记录基线信息:
  • 测试通过数量
  • 测试执行时长
  • 跳过的测试数量

Step 1: Analyze Target

步骤1:分析目标

Target mode: Read the target code. Identify:
  • Cyclomatic complexity (count branches, loops, conditions)
  • Function length (lines)
  • Parameter count
  • Nesting depth
  • Code duplication
  • Naming clarity
Sweep mode: Run
/complexity
on the scope to get a ranked list of targets:
/complexity <scope>
Sort by complexity score descending. Work the worst offenders first.
Extract mode: Read the target and identify the extraction boundary:
  • What code moves out?
  • What interface connects the pieces?
  • What are the inputs and outputs of the extracted unit?
目标模式: 阅读目标代码,识别以下问题:
  • 圈复杂度(分支、循环、条件判断数量)
  • 函数长度(代码行数)
  • 参数数量
  • 嵌套深度
  • 代码重复
  • 命名清晰度
扫描模式: 在目标范围运行
/complexity
获取排序后的目标列表:
/complexity <scope>
按复杂度得分降序排序,优先处理问题最严重的代码。
提取模式: 阅读目标代码,确定提取边界:
  • 哪些代码需要移出?
  • 各模块之间用什么接口连接?
  • 提取单元的输入和输出分别是什么?

Step 2: Plan Refactoring

步骤2:规划重构方案

For each target, produce a numbered list of specific transformations:
1. Extract lines 45-78 of processConfig() into validateConfig()
2. Replace nested if/else at line 92 with guard clause + early return
3. Rename `cfg` to `clusterConfig` for clarity
4. Inline single-use helper `tmpName()` at line 120
For each transformation, identify:
  • Which tests cover it -- grep for test functions that exercise the target
  • Risk level -- low (rename, formatting), medium (extract, inline), high (interface change, moved code)
  • Order dependency -- does this step depend on a prior step?
If no tests cover the target: write tests FIRST. Do not refactor untested code.
为每个重构目标生成编号的具体转换步骤列表:
1. 将processConfig()的45-78行提取为validateConfig()
2. 将第92行的嵌套if/else替换为守卫子句+提前返回
3. 为提高清晰度将`cfg`重命名为`clusterConfig`
4. 内联第120行仅使用一次的辅助函数`tmpName()`
为每个转换步骤确认:
  • 覆盖该部分的测试用例——搜索调用目标代码的测试函数
  • 风险等级——低(重命名、格式调整)、中(提取、内联)、高(接口变更、代码迁移)
  • 顺序依赖——当前步骤是否依赖之前的步骤?
如果目标代码没有测试覆盖:优先编写测试用例。不要重构未经过测试的代码。

Step 3: Execute Step-by-Step

步骤3:逐步骤执行

For EACH transformation in the plan:
对规划中的每一个转换步骤:

3a. Make ONE transformation

3a. 执行单次转换

Apply a single, focused change. Do not combine multiple transformations. Keep the diff minimal and reviewable.
仅应用单个聚焦的变更,不要合并多个转换操作。保持diff最小且可评审。

3b. Run tests immediately

3b. 立即运行测试

bash
undefined
bash
undefined

Go

Go

cd cli && go test ./...
cd cli && go test ./...

Python

Python

pytest
pytest

Or the project-specific test command

或项目自定义的测试命令

undefined
undefined

3c. Evaluate result

3c. 评估执行结果

Tests pass:
  • Commit with conventional commit format:
    refactor(<scope>): <description>
    Examples:
    • refactor(goals): extract validateConfig from processConfig
    • refactor(hooks): simplify conditional logic in pre-push gate
    • refactor(cli): reduce parameter count in NewCommand
Tests fail:
  • Revert the change immediately. Do not debug on top of a broken refactor.
  • Re-read the failing test to understand what contract was violated.
  • Re-analyze the transformation -- was the approach wrong, or was the scope too large?
  • Retry with a smaller, safer transformation.
测试通过:
  • 使用约定式提交格式提交代码:
    refactor(<scope>): <description>
    示例:
    • refactor(goals): extract validateConfig from processConfig
    • refactor(hooks): simplify conditional logic in pre-push gate
    • refactor(cli): reduce parameter count in NewCommand
测试失败:
  • 立即回滚变更。 不要在损坏的重构基础上调试问题。
  • 重新阅读失败的测试用例,理解违反了什么契约。
  • 重新分析转换方案——是方法错误还是范围过大?
  • 尝试更小、更安全的转换操作。

3d. Proceed to next transformation

3d. 继续下一个转换步骤

Repeat 3a-3c for each planned step. After completing all steps for a target, move to Step 4.
对所有规划步骤重复3a-3c。完成单个目标的所有步骤后,进入步骤4。

Step 4: Post-Refactor Verification

步骤4:重构后验证

After all transformations are complete:
  1. Run full test suite -- not just the targeted tests, the entire suite:
    bash
    cd cli && go test ./...
  2. Run complexity analysis on changed files:
    /complexity <changed-files>
  3. Compare before/after metrics:
    MetricBeforeAfterDelta
    Cyclomatic complexity???
    Lines of code???
    Function count???
    Max nesting depth???
    Test count???
  4. Verify no behavioral change -- the refactored code must do exactly what the old code did. If tests were added, they must pass against BOTH the old and new code.
所有转换完成后:
  1. 运行完整测试套件——不只是目标测试用例,而是全量测试:
    bash
    cd cli && go test ./...
  2. 对变更文件运行复杂度分析
    /complexity <changed-files>
  3. 对比前后指标:
    指标重构前重构后变化
    圈复杂度???
    代码行数???
    函数数量???
    最大嵌套深度???
    测试数量???
  4. 验证无行为变更——重构后的代码必须和旧代码功能完全一致。如果新增了测试用例,必须同时通过新旧代码的验证。

Step 5: Output Summary

步骤5:输出总结

Write a refactoring summary to
.agents/refactor/
:
bash
mkdir -p .agents/refactor
File:
.agents/refactor/YYYY-MM-DD-refactor-<scope>.md
Content:
markdown
undefined
将重构总结写入
.agents/refactor/
目录:
bash
mkdir -p .agents/refactor
文件路径:
.agents/refactor/YYYY-MM-DD-refactor-<scope>.md
内容:
markdown
undefined

Refactor: <scope>

重构:<scope>

Date: YYYY-MM-DD Mode: target | sweep | extract Files changed: <count>
日期: YYYY-MM-DD 模式: target | sweep | extract 变更文件数: <count>

Targets

重构目标

  • file:function -- <what was done>
  • file:function -- <完成的操作>

Metrics

指标对比

MetricBeforeAfterDelta
Cyclomatic complexityXY-Z
Lines of codeXY-Z
Max nesting depthXY-Z
指标重构前重构后变化
圈复杂度XY-Z
代码行数XY-Z
最大嵌套深度XY-Z

Transformations Applied

应用的转换操作

  1. <description> -- <commit hash>
  2. <description> -- <commit hash>
  1. <描述> -- <提交哈希>
  2. <描述> -- <提交哈希>

Tests

测试情况

  • Baseline: X passing, Y skipped
  • Final: X passing, Y skipped
  • New tests added: Z
  • 基线:X个通过,Y个跳过
  • 最终:X个通过,Y个跳过
  • 新增测试用例:Z个

Learnings

经验总结

  • <anything worth noting for future refactors>
undefined
  • <未来重构值得注意的内容>
undefined

Refactoring Catalog

重构目录

Extract Method

提取方法

When: Function exceeds 30 lines, or a block of code has a clear single purpose.
Pattern:
Before: longFunction() { ... block A ... block B ... block C ... }
After:  longFunction() { doA(); doB(); doC(); }
        doA() { ... block A ... }
        doB() { ... block B ... }
        doC() { ... block C ... }
Safety: Low risk if inputs/outputs are clear. Watch for:
  • Shared local variables -- pass as parameters or return as values
  • Error handling -- propagate errors from extracted functions
  • Side effects -- document any mutations
适用场景: 函数超过30行,或某段代码有明确的单一职责。
模式:
重构前:longFunction() { ... 块A ... 块B ... 块C ... }
重构后:longFunction() { doA(); doB(); doC(); }
        doA() { ... 块A ... }
        doB() { ... 块B ... }
        doC() { ... 块C ... }
安全性: 输入输出清晰的情况下风险低。注意:
  • 共享局部变量——作为参数传递或作为返回值返回
  • 错误处理——从提取函数中正确传播错误
  • 副作用——记录所有变更操作

Extract Module

提取模块

When: A file exceeds 500 lines, or contains multiple unrelated concerns.
Pattern:
Before: god_file.go (800 lines, 5 concerns)
After:  config.go (validation, loading)
        metrics.go (collection, reporting)
        handlers.go (request handling)
Safety: Medium risk. Watch for:
  • Circular imports between new modules
  • Package-level variables shared across concerns
  • Init functions with ordering dependencies
适用场景: 单个文件超过500行,或包含多个不相关的职责。
模式:
重构前:god_file.go (800行,5个职责)
重构后:config.go (校验、加载)
        metrics.go (采集、上报)
        handlers.go (请求处理)
安全性: 中等风险。注意:
  • 新模块之间的循环导入
  • 跨职责共享的包级变量
  • 存在顺序依赖的Init函数

Rename

重命名

When: A name is ambiguous, misleading, or uses abbreviations that obscure meaning.
Pattern:
Before: func proc(cfg *C) error
After:  func processClusterConfig(config *ClusterConfig) error
Safety: Low risk with tooling. Always:
  • Search for ALL references (including string literals, comments, docs)
  • Update test assertions that reference the old name
  • Check exported symbols -- renaming public APIs is a breaking change
适用场景: 命名模糊、有误导性,或使用了含义不清晰的缩写。
模式:
重构前:func proc(cfg *C) error
重构后:func processClusterConfig(config *ClusterConfig) error
安全性: 有工具支持的情况下风险低。始终需要:
  • 搜索所有引用(包括字符串字面量、注释、文档)
  • 更新引用旧名称的测试断言
  • 检查导出符号——重命名公共API属于破坏性变更

Inline

内联

When: A function or variable adds indirection without adding clarity. Single-use helpers that obscure the flow.
Pattern:
Before: x := getName(item)    // func getName(i Item) string { return i.Name }
After:  x := item.Name
Safety: Low risk. Verify the inlined code does not have side effects you are hiding.
适用场景: 函数或变量增加了间接层级但没有提升清晰度,仅使用一次的辅助函数遮挡了代码流程。
模式:
重构前:x := getName(item)    // func getName(i Item) string { return i.Name }
重构后:x := item.Name
安全性: 低风险。验证内联代码没有被隐藏的副作用。

Simplify Conditional

简化条件判断

When: Nested if/else chains exceed 3 levels, or boolean expressions are complex.
Patterns:
  • Guard clauses: Move error/edge cases to top with early return
  • Early return: Eliminate else branches by returning early
  • Table-driven logic: Replace long switch/case with map lookup
  • Polymorphism: Replace type-based switching with interface dispatch
Before:
  if err != nil {
      if isRetryable(err) {
          if attempts < max {
              retry()
          } else {
              fail()
          }
      } else {
          fail()
      }
  } else {
      succeed()
  }

After:
  if err == nil {
      succeed()
      return
  }
  if !isRetryable(err) || attempts >= max {
      fail()
      return
  }
  retry()
适用场景: 嵌套if/else链超过3层,或布尔表达式过于复杂。
模式:
  • 守卫子句: 将错误/边缘场景移到代码顶部并提前返回
  • 提前返回: 通过提前返回消除else分支
  • 表驱动逻辑: 用map查找替换冗长的switch/case
  • 多态: 用接口分发替换基于类型的分支判断
重构前:
  if err != nil {
      if isRetryable(err) {
          if attempts < max {
              retry()
          } else {
              fail()
          }
      } else {
          fail()
      }
  } else {
      succeed()
  }

重构后:
  if err == nil {
      succeed()
      return
  }
  if !isRetryable(err) || attempts >= max {
      fail()
      return
  }
  retry()

Reduce Parameters

减少参数数量

When: A function takes more than 4 parameters.
Pattern:
Before: func deploy(name, ns, image string, replicas int, labels map[string]string, timeout time.Duration) error
After:  func deploy(opts DeployOptions) error

type DeployOptions struct {
    Name     string
    NS       string
    Image    string
    Replicas int
    Labels   map[string]string
    Timeout  time.Duration
}
Safety: Medium risk -- all callers must be updated. Use the struct field convention from
go.md
: grep all call sites and update each one.
适用场景: 函数参数超过4个。
模式:
重构前:func deploy(name, ns, image string, replicas int, labels map[string]string, timeout time.Duration) error
重构后:func deploy(opts DeployOptions) error

type DeployOptions struct {
    Name     string
    NS       string
    Image    string
    Replicas int
    Labels   map[string]string
    Timeout  time.Duration
}
安全性: 中等风险——需要更新所有调用方。遵循
go.md
中的结构体字段约定:搜索所有调用点逐个更新。

Remove Dead Code

移除死代码

When: Functions, variables, constants, or types are defined but never referenced.
How to identify:
bash
undefined
适用场景: 定义了但从未被引用的函数、变量、常量或类型。
识别方法:
bash
undefined

Go: unused exports

Go: 未使用的导出符号

go vet ./...
go vet ./...

Or use staticcheck, deadcode, or unparam tools

或使用staticcheck、deadcode、unparam工具

Python: vulture or pylint unused-import

Python: vulture或pylint unused-import

vulture <directory>

**Safety:** Low risk for truly dead code. But verify:
- Not called via reflection or string-based dispatch
- Not part of an interface implementation
- Not used in build tags or conditional compilation
- Not referenced in external packages (if this is a library)
vulture <directory>

**安全性:** 确认是死代码的情况下风险低。但需要验证:
- 没有通过反射或基于字符串的分发调用
- 不是接口实现的一部分
- 没有在构建标签或条件编译中使用
- 没有被外部包引用(如果是库项目)

Guardrails

约束规则

What NOT to Refactor

禁止重构的场景

  • Code you don't understand. Read it, test it, understand it -- THEN refactor.
  • Code without tests. Write tests first. Refactoring untested code is gambling.
  • Code under active development. If someone else is working on it, coordinate first.
  • Performance-critical hot paths without benchmarks. Measure before and after.
  • 你不理解的代码。 先阅读、测试、理解代码——再进行重构。
  • 没有测试覆盖的代码。 优先编写测试用例,重构未测试代码属于赌博行为。
  • 处于活跃开发中的代码。 如果有其他人正在开发该部分代码,先进行协调。
  • 性能关键路径 没有基准测试的情况下,需要在重构前后测量性能。

When to Stop

停止重构的时机

  • Diminishing returns. If complexity dropped from 45 to 12, don't chase 8.
  • Test instability. If tests start flaking, stop and stabilize.
  • Scope creep. Refactoring should not change behavior. If you find a bug, file an issue -- don't fix it mid-refactor.
  • Time budget exceeded. Set a timebox. Refactoring expands to fill available time.
  • 收益递减。 如果复杂度从45降到12,不用强求降到8。
  • 测试不稳定。 如果测试开始出现偶现失败,停止重构先稳定测试。
  • 范围蔓延。 重构不应该变更代码行为,如果发现bug,提交issue——不要在重构过程中修复。
  • 超出时间预算。 设置时间盒,重构工作会自动膨胀填满所有可用时间。

Red Flags During Refactoring

重构过程中的危险信号

  • Tests pass but you changed behavior (test gap -- add a test)
  • You need to refactor the tests to make them pass (you broke the contract)
  • The diff is growing beyond what you can review in one sitting (split into smaller PRs)
  • You are renaming things to match your preference, not for clarity (stop)
  • 测试通过但你修改了代码行为(存在测试缺口——新增测试用例)
  • 你需要修改测试用例才能让测试通过(你破坏了代码契约)
  • diff的大小超出了你单次可以评审的范围(拆分为更小的PR)
  • 你按照个人偏好重命名而非为了提升清晰度(立即停止)

See Also

另请参阅

  • /complexity
    -- analyze code complexity metrics
  • /standards
    -- language-specific conventions
  • /vibe
    -- validate code quality post-refactor
  • /bug-hunt
    -- if refactoring uncovers bugs
  • /implement
    -- if refactoring requires new code
  • /complexity
    ——分析代码复杂度指标
  • /standards
    ——语言特定的编码规范
  • /vibe
    ——重构后验证代码质量
  • /bug-hunt
    ——如果重构过程中发现了bug
  • /implement
    ——如果重构需要新增代码