code-refactor

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Code Refactor

代码重构

Overview

概述

This skill guides systematic refactoring of one or more codebase components through three phases:
  1. Research - Deep analysis of component behavior, usage patterns, and dependencies
  2. Proposal - Concrete change suggestions with code samples and impact analysis
  3. Test Plan - Test strategy to validate changes without regressions
Each phase produces a markdown document, creating a complete refactoring proposal that can be reviewed before implementation.
本Skill通过三个阶段指导对一个或多个代码库组件进行系统性重构:
  1. 调研 - 深入分析组件行为、使用模式和依赖关系
  2. 提案 - 提供具体的变更建议,附带代码示例和影响分析
  3. 测试计划 - 制定测试策略,在不引入回归问题的前提下验证变更
每个阶段都会生成一份Markdown文档,形成一套完整的重构提案,可在实施前进行评审。

Output Structure

输出结构

Ask the user for an output directory (e.g.,
./docs/refactoring/
or
./proposals/
).
Create a subfolder for the refactoring effort:
{output-directory}/
└── {component-name}-refactor/
    ├── 01-research.md      # Phase 1: Component Analysis
    ├── 02-proposal.md      # Phase 2: Change Proposals
    └── 03-test-plan.md     # Phase 3: Test Strategy
For multi-component refactoring, create subfolders:
{output-directory}/
└── {thread-name}-refactor/
    ├── component-a/
    │   ├── 01-research.md
    │   ├── 02-proposal.md
    │   └── 03-test-plan.md
    └── component-b/
        ├── 01-research.md
        ├── 02-proposal.md
        └── 03-test-plan.md

请向用户确认输出目录(例如:
./docs/refactoring/
./proposals/
)。
为重构工作创建子文件夹:
{output-directory}/
└── {component-name}-refactor/
    ├── 01-research.md      # 阶段1:组件分析
    ├── 02-proposal.md      # 阶段2:变更提案
    └── 03-test-plan.md     # 阶段3:测试策略
针对多组件重构,创建如下子文件夹结构:
{output-directory}/
└── {thread-name}-refactor/
    ├── component-a/
    │   ├── 01-research.md
    │   ├── 02-proposal.md
    │   └── 03-test-plan.md
    └── component-b/
        ├── 01-research.md
        ├── 02-proposal.md
        └── 03-test-plan.md

Phase 1: Research

阶段1:调研

Goal: Comprehensive understanding of the component before proposing changes.
For multi-component refactoring, use parallel Explore agents to research each component simultaneously, then synthesize findings.
目标:在提出变更前全面了解组件情况。
针对多组件重构,使用并行Explore Agent同时调研每个组件,然后整合调研结果。

Step 1: Component Inventory (Use /codebase-librarian)

步骤1:组件清单(使用/codebase-librarian)

Start with the
/codebase-librarian
skill to establish baseline understanding:
  • Project foundation (language, tooling)
  • Entry points relevant to the component
  • Services the component interacts with
  • Infrastructure dependencies
  • Domain model elements involved
This provides context for the deeper component analysis that follows.
首先使用
/codebase-librarian
Skill建立基础认知:
  • 项目基础信息(语言、工具链)
  • 与该组件相关的入口点
  • 组件交互的服务
  • 基础设施依赖
  • 涉及的领域模型元素
这为后续的组件深度分析提供上下文信息。

Step 2: Component Deep Dive

步骤2:组件深度剖析

After the inventory, analyze the specific component(s) being refactored.
Understand how it works:
  • Core responsibilities and behavior
  • Internal structure and control flow
  • State management and data transformations
  • Error handling patterns
  • Configuration and initialization
Understand instantiation and usage:
  • Where is it instantiated?
  • How many instantiation patterns exist?
  • What parameters/dependencies are injected?
  • Is it a singleton, factory-created, or ad-hoc?
Map the surroundings:
  • Dependents (what calls this component)
  • Dependencies (what this component calls)
  • Before: What happens before invocation?
  • After: What happens after invocation?
完成清单梳理后,分析待重构的特定组件。
了解组件工作原理:
  • 核心职责与行为
  • 内部结构与控制流
  • 状态管理与数据转换
  • 错误处理模式
  • 配置与初始化流程
了解实例化与使用方式:
  • 组件在何处实例化?
  • 存在多少种实例化模式?
  • 注入了哪些参数/依赖?
  • 是单例、工厂创建还是临时创建的?
梳理周边关联:
  • 依赖方(调用该组件的对象)
  • 被依赖方(该组件调用的对象)
  • 调用前:调用该组件前通常会发生什么?
  • 调用后:调用结果会被用于什么场景?

Step 3: Call Graph

步骤3:调用关系图

Create a visual representation of the component's call relationships:
┌─────────────────────────────────────────────────────────────┐
│                        CALLERS                              │
├─────────────────────────────────────────────────────────────┤
│  OrderController.create()  ──┐                              │
│  OrderController.update()  ──┼──► PaymentService            │
│  CheckoutWorker.process()  ──┘                              │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│                    PaymentService                           │
├─────────────────────────────────────────────────────────────┤
│  processPayment()                                           │
│  refundPayment()                                            │
│  validateCard()                                             │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│                      DEPENDENCIES                           │
├─────────────────────────────────────────────────────────────┤
│  StripeClient          │  PaymentRepository                 │
│  FraudDetectionService │  EventEmitter                      │
└─────────────────────────────────────────────────────────────┘
创建组件调用关系的可视化表示:
┌─────────────────────────────────────────────────────────────┐
│                        调用方                              │
├─────────────────────────────────────────────────────────────┤
│  OrderController.create()  ──┐                              │
│  OrderController.update()  ──┼──► PaymentService            │
│  CheckoutWorker.process()  ──┘                              │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│                    PaymentService                           │
├─────────────────────────────────────────────────────────────┤
│  processPayment()                                           │
│  refundPayment()                                            │
│  validateCard()                                             │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│                      被依赖方                               │
├─────────────────────────────────────────────────────────────┤
│  StripeClient          │  PaymentRepository                 │
│  FraudDetectionService │  EventEmitter                      │
└─────────────────────────────────────────────────────────────┘

Research Output Format

调研输出格式

Write to
01-research.md
:
markdown
undefined
写入
01-research.md
markdown
undefined

Research: [Component Name]

调研:[组件名称]

Generated: [Date] Scope: [Component path/module]
生成日期:[日期] 范围:[组件路径/模块]

Executive Summary

执行摘要

[2-3 paragraphs covering:]
  • Component's purpose and role in the system
  • Key findings about current implementation
  • Areas of concern or complexity discovered
[2-3段内容,涵盖:]
  • 组件在系统中的用途与角色
  • 当前实现的关键发现
  • 发现的问题或复杂点

Component Analysis

组件分析

Core Behavior

核心行为

[What the component does, its responsibilities]
[组件的功能、职责]

Internal Structure

内部结构

[Classes, functions, modules that compose it]
[组成该组件的类、函数、模块]

State & Data Flow

状态与数据流

[How data moves through the component]
[数据在组件中的流转方式]

Instantiation Patterns

实例化模式

LocationPatternParametersFrequency
src/api/orders.ts:45
Direct newconfig, logger3 places
src/workers/checkout.ts:12
Factoryconfig1 place
位置模式参数出现频率
src/api/orders.ts:45
直接newconfig, logger3处
src/workers/checkout.ts:12
工厂模式config1处

Dependency Analysis

依赖分析

Dependents (Who calls this)

依赖方(调用当前组件的对象)

CallerMethodContext
OrderController
processPayment()
HTTP request handling
CheckoutWorker
processPayment()
Background job
调用方方法上下文
OrderController
processPayment()
HTTP请求处理
CheckoutWorker
processPayment()
后台任务

Dependencies (What this calls)

被依赖方(当前组件调用的对象)

DependencyUsageAbstracted?
StripeClient
Payment processingNo - direct SDK
PaymentRepository
PersistenceYes - interface
依赖项使用场景是否抽象化
StripeClient
支付处理否 - 直接调用SDK
PaymentRepository
持久化是 - 基于接口

Execution Context

执行上下文

Before invocation: [What typically happens before this component is called] After invocation: [What happens with the result]
调用前:[调用该组件前通常会发生的操作] 调用后:[调用结果的后续处理]

Call Graph

调用关系图

[ASCII diagram as shown above]
[如上方所示的ASCII图]

Key Observations

关键发现

  • [Notable pattern or concern 1]
  • [Notable pattern or concern 2]
  • [Areas that may need attention during refactoring]

---
  • [值得注意的模式或问题1]
  • [值得注意的模式或问题2]
  • [重构期间需要关注的领域]

---

Phase 2: Proposal

阶段2:提案

Persona: Pragmatic Senior Engineer
Mindset: Balance ideal architecture with practical constraints. Quick wins build momentum and trust. Large changes need clear justification. Every change should have a clear "why".
角色定位:务实的资深工程师
思维模式:平衡理想架构与实际约束。快速小赢能建立动力与信任。大型变更需要明确的理由。每一项变更都应有清晰的“为什么”。

Proposal Structure

提案结构

Order changes from quick wins to complex restructuring:
  1. Quick Wins - Small, low-risk improvements (hours)
  2. Medium Changes - Meaningful refactoring (days)
  3. Large Restructuring - Significant architectural changes (weeks)
按从快速优化到复杂重构的顺序排列变更:
  1. 快速优化 - 小型、低风险的改进(耗时数小时)
  2. 中型变更 - 有实际意义的重构(耗时数天)
  3. 大型架构调整 - 重大的架构变更(耗时数周)

For Each Change

每项变更需包含

Provide:
  1. Problem Statement - What's wrong and why it matters
  2. Proposed Solution - Concrete approach
  3. Code Samples - Before and after comparisons
  4. Impact Analysis - Files affected, risks, dependencies
  5. Pros and Cons - Honest trade-off assessment
提供:
  1. 问题陈述 - 存在的问题及其影响
  2. 解决方案 - 具体实现方案
  3. 代码示例 - 变更前后的代码对比
  4. 影响分析 - 受影响的文件、风险、依赖关系
  5. 优缺点 - 客观的权衡评估

Proposal Output Format

提案输出格式

Write to
02-proposal.md
:
markdown
undefined
写入
02-proposal.md
markdown
undefined

Refactoring Proposal: [Component Name]

重构提案:[组件名称]

Generated: [Date] Based on: 01-research.md
生成日期:[日期] 基于文档:01-research.md

Executive Summary

执行摘要

[Overview of proposed changes, expected benefits, and effort distribution]

[概述提议的变更、预期收益与工作量分布]

Quick Wins

快速优化

1. [Change Title]

1. [变更标题]

Problem [What's wrong - reference research findings]
Solution [What to do]
Before
typescript
// src/services/payment.ts:45-52
class PaymentService {
  constructor() {
    this.stripe = new Stripe(process.env.STRIPE_KEY);
  }
}
After
typescript
// src/services/payment.ts:45-55
class PaymentService {
  constructor(private readonly paymentGateway: PaymentGateway) {}
}

// src/ports/payment-gateway.ts (new)
interface PaymentGateway {
  charge(amount: number, currency: string): Promise<ChargeResult>;
}
Impact
  • Files modified:
    src/services/payment.ts
    ,
    src/composition-root.ts
  • Files created:
    src/ports/payment-gateway.ts
  • Risk: Low - constructor signature change requires updating instantiation sites
Pros
  • Enables unit testing without Stripe sandbox
  • Prepares for potential payment provider switch
Cons
  • Adds indirection layer
  • Requires updating 3 instantiation sites

问题 [存在的问题 - 参考调研结果]
解决方案 [具体操作]
变更前
typescript
// src/services/payment.ts:45-52
class PaymentService {
  constructor() {
    this.stripe = new Stripe(process.env.STRIPE_KEY);
  }
}
变更后
typescript
// src/services/payment.ts:45-55
class PaymentService {
  constructor(private readonly paymentGateway: PaymentGateway) {}
}

// src/ports/payment-gateway.ts (新增)
interface PaymentGateway {
  charge(amount: number, currency: string): Promise<ChargeResult>;
}
影响
  • 修改的文件:
    src/services/payment.ts
    ,
    src/composition-root.ts
  • 新增的文件:
    src/ports/payment-gateway.ts
  • 风险:低 - 构造函数签名变更需要更新所有实例化位置
优点
  • 无需Stripe沙箱即可进行单元测试
  • 为后续切换支付服务商做准备
缺点
  • 增加了一层间接调用
  • 需要更新3处实例化代码

Medium Changes

中型变更

2. [Change Title]

2. [变更标题]

[Same structure as above]

[与上述结构相同]

Large Restructuring

大型架构调整

3. [Change Title]

3. [变更标题]

[Same structure - may be higher level for larger efforts]

[与上述结构相同 - 大型变更可采用更高层级的描述]

Implementation Order

实施顺序

Recommended sequence considering dependencies:
  1. [Quick Win 1] - No dependencies
  2. [Quick Win 2] - No dependencies
  3. [Medium Change 1] - Depends on Quick Win 1
  4. [Large Restructuring] - Depends on Medium Change 1
考虑依赖关系的推荐执行顺序:
  1. [快速优化1] - 无依赖
  2. [快速优化2] - 无依赖
  3. [中型变更1] - 依赖快速优化1
  4. [大型架构调整] - 依赖中型变更1

Risk Assessment

风险评估

ChangeRisk LevelMitigation
[Change 1]LowExisting tests cover behavior
[Change 2]MediumAdd integration tests first
[Change 3]HighFeature flag, gradual rollout

---
变更风险等级缓解措施
[变更1]现有测试覆盖核心行为
[变更2]先新增集成测试
[变更3]使用功能开关,逐步灰度发布

---

Phase 3: Test Plan

阶段3:测试计划

Goal: Design tests that validate refactoring without regressions.
目标:设计测试用例,在不引入回归问题的前提下验证重构效果。

Analysis Steps

分析步骤

  1. Audit existing tests - What's already covered?
  2. Identify gaps - What behavior lacks test coverage?
  3. Design new tests - Focus on integration over unit tests
  4. Minimize mocks - Prefer real dependencies when feasible
  1. 审核现有测试 - 已覆盖哪些场景?
  2. 识别测试缺口 - 哪些行为缺乏测试覆盖?
  3. 设计新测试 - 优先关注集成测试而非单元测试
  4. 最小化Mock使用 - 尽可能使用真实依赖

Test Philosophy

测试理念

  • Favor integration tests - Test real interactions between components
  • Use mocks sparingly - Only for external services, not internal dependencies
  • Test behavior, not implementation - Tests should survive refactoring
  • Cover edge cases discovered in research - Use Phase 1 findings
  • 优先集成测试 - 测试组件间的真实交互
  • 谨慎使用Mock - 仅用于外部服务,不用于内部依赖
  • 测试行为而非实现 - 测试用例应能在重构后依然有效
  • 覆盖调研中发现的边缘场景 - 利用阶段1的调研结果

Test Plan Output Format

测试计划输出格式

Write to
03-test-plan.md
:
markdown
undefined
写入
03-test-plan.md
markdown
undefined

Test Plan: [Component Name] Refactoring

测试计划:[组件名称]重构

Generated: [Date] Based on: 01-research.md, 02-proposal.md
生成日期:[日期] 基于文档:01-research.md, 02-proposal.md

Executive Summary

执行摘要

[Overview of testing strategy and coverage goals]
[概述测试策略与覆盖目标]

Current Test Coverage

当前测试覆盖情况

Existing Tests

现有测试

Test FileTypeCoverageNotes
payment.test.ts
UnitCore payment flowHeavy mocking
checkout.integration.ts
IntegrationHappy path onlyNo error cases
测试文件类型覆盖范围备注
payment.test.ts
单元测试核心支付流程大量使用Mock
checkout.integration.ts
集成测试仅 happy path未覆盖错误场景

Coverage Gaps

测试缺口

  • Error handling in
    processPayment()
  • Concurrent payment attempts
  • Retry behavior after transient failures
  • processPayment()
    的错误处理
  • 并发支付尝试
  • 临时故障后的重试行为

Test Strategy

测试策略

Integration Tests (Preferred)

集成测试(优先选择)

Tests that exercise real component interactions:
Test: Payment processing end-to-end
typescript
// tests/integration/payment.test.ts
describe('PaymentService', () => {
  let service: PaymentService;
  let testDb: TestDatabase;

  beforeEach(async () => {
    testDb = await TestDatabase.create();
    service = new PaymentService(
      new StripeTestGateway(),  // Test mode, real API
      new PaymentRepository(testDb)
    );
  });

  it('processes payment and persists record', async () => {
    const result = await service.processPayment({
      amount: 1000,
      currency: 'usd',
      customerId: 'cust_123'
    });

    expect(result.status).toBe('succeeded');

    const record = await testDb.payments.findById(result.id);
    expect(record).toBeDefined();
    expect(record.amount).toBe(1000);
  });
});
Why integration over unit: Tests real database interactions, actual service coordination, and catches integration bugs that mocks would hide.
测试组件间真实交互的用例:
测试:支付处理端到端流程
typescript
// tests/integration/payment.test.ts
describe('PaymentService', () => {
  let service: PaymentService;
  let testDb: TestDatabase;

  beforeEach(async () => {
    testDb = await TestDatabase.create();
    service = new PaymentService(
      new StripeTestGateway(),  // 测试模式,调用真实API
      new PaymentRepository(testDb)
    );
  });

  it('处理支付并持久化记录', async () => {
    const result = await service.processPayment({
      amount: 1000,
      currency: 'usd',
      customerId: 'cust_123'
    });

    expect(result.status).toBe('succeeded');

    const record = await testDb.payments.findById(result.id);
    expect(record).toBeDefined();
    expect(record.amount).toBe(1000);
  });
});
为什么优先集成测试:测试真实的数据库交互、服务协作,能捕获Mock无法发现的集成问题。

Unit Tests (When Necessary)

单元测试(必要时使用)

Use unit tests with mocks only when:
  • External API calls would be slow/costly
  • Testing pure business logic in isolation
  • Simulating error conditions difficult to reproduce
Test: Fraud detection logic
typescript
// tests/unit/fraud-detection.test.ts
describe('FraudDetector', () => {
  it('flags high-risk transactions', () => {
    const detector = new FraudDetector();

    const result = detector.assess({
      amount: 10000,
      newCustomer: true,
      internationalCard: true
    });

    expect(result.riskLevel).toBe('high');
    expect(result.requiresReview).toBe(true);
  });
});
Why unit here: Pure logic, no external dependencies, fast execution.
仅在以下场景使用带Mock的单元测试:
  • 外部API调用缓慢/产生费用
  • 隔离测试纯业务逻辑
  • 模拟难以复现的错误场景
测试:欺诈检测逻辑
typescript
// tests/unit/fraud-detection.test.ts
describe('FraudDetector', () => {
  it('标记高风险交易', () => {
    const detector = new FraudDetector();

    const result = detector.assess({
      amount: 10000,
      newCustomer: true,
      internationalCard: true
    });

    expect(result.riskLevel).toBe('high');
    expect(result.requiresReview).toBe(true);
  });
});
为什么此处用单元测试:纯逻辑,无外部依赖,执行速度快。

Tests Per Proposal Change

针对每项提案变更的测试

For Change 1: [Extract PaymentGateway Interface]

针对变更1:[提取PaymentGateway接口]

TestTypePurpose
gateway-contract.test.ts
ContractVerify adapter implements interface correctly
payment-with-mock-gateway.test.ts
UnitVerify service works with any gateway
New test:
typescript
// tests/contract/payment-gateway.test.ts
describe('PaymentGateway contract', () => {
  const adapters = [
    ['Stripe', () => new StripePaymentAdapter(stripeTestClient)],
    ['Mock', () => new MockPaymentAdapter()],
  ];

  test.each(adapters)('%s adapter implements contract', (name, createAdapter) => {
    const adapter = createAdapter();

    expect(adapter.charge).toBeDefined();
    expect(adapter.refund).toBeDefined();
  });
});
测试类型目的
gateway-contract.test.ts
契约测试验证适配器是否正确实现接口
payment-with-mock-gateway.test.ts
单元测试验证服务可与任意网关配合工作
新增测试:
typescript
// tests/contract/payment-gateway.test.ts
describe('PaymentGateway契约', () => {
  const adapters = [
    ['Stripe', () => new StripePaymentAdapter(stripeTestClient)],
    ['Mock', () => new MockPaymentAdapter()],
  ];

  test.each(adapters)('%s适配器实现契约', (name, createAdapter) => {
    const adapter = createAdapter();

    expect(adapter.charge).toBeDefined();
    expect(adapter.refund).toBeDefined();
  });
});

For Change 2: [Change Title]

针对变更2:[变更标题]

[Similar structure]
[类似结构]

Mock Usage Guidelines

Mock使用指南

Acceptable mocks:
  • External payment APIs (Stripe, PayPal)
  • Email services
  • SMS/notification services
  • Third-party APIs with rate limits
Avoid mocking:
  • Internal services (use real implementations)
  • Repositories (use test database)
  • Domain logic (test directly)
可接受的Mock场景:
  • 外部支付API(Stripe、PayPal)
  • 邮件服务
  • SMS/通知服务
  • 有调用限制的第三方API
应避免的Mock场景:
  • 内部服务(使用真实实现)
  • 仓库(使用测试数据库)
  • 领域逻辑(直接测试)

Verification Checklist

验证 checklist

Before considering refactoring complete:
  • All existing tests pass
  • New integration tests cover changed behavior
  • Edge cases from research are tested
  • Error handling paths have coverage
  • No increase in mock usage
  • CI pipeline green

---
重构完成前需确认:
  • 所有现有测试通过
  • 新增集成测试覆盖变更行为
  • 调研中发现的边缘场景已测试
  • 错误处理路径已覆盖
  • Mock使用未增加
  • CI流水线执行成功

---

References

参考资料

For detailed guidance on each phase:
  • Phase 1 deep dive: See references/research-phase.md for advanced research techniques
  • Phase 2 patterns: See references/proposal-phase.md for common refactoring patterns
  • Phase 3 testing: See references/test-plan-phase.md for test design patterns
各阶段的详细指导:
  • 阶段1深度指南:查看references/research-phase.md了解高级调研技巧
  • 阶段2模式参考:查看references/proposal-phase.md了解常见重构模式
  • 阶段3测试指南:查看references/test-plan-phase.md了解测试设计模式