code-refactor
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCode Refactor
代码重构
Overview
概述
This skill guides systematic refactoring of one or more codebase components through three phases:
- Research - Deep analysis of component behavior, usage patterns, and dependencies
- Proposal - Concrete change suggestions with code samples and impact analysis
- 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通过三个阶段指导对一个或多个代码库组件进行系统性重构:
- 调研 - 深入分析组件行为、使用模式和依赖关系
- 提案 - 提供具体的变更建议,附带代码示例和影响分析
- 测试计划 - 制定测试策略,在不引入回归问题的前提下验证变更
每个阶段都会生成一份Markdown文档,形成一套完整的重构提案,可在实施前进行评审。
Output Structure
输出结构
Ask the user for an output directory (e.g., or ).
./docs/refactoring/./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 StrategyFor 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.mdPhase 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 skill to establish baseline understanding:
/codebase-librarian- 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.
首先使用 Skill建立基础认知:
/codebase-librarian- 项目基础信息(语言、工具链)
- 与该组件相关的入口点
- 组件交互的服务
- 基础设施依赖
- 涉及的领域模型元素
这为后续的组件深度分析提供上下文信息。
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.mdmarkdown
undefined写入:
01-research.mdmarkdown
undefinedResearch: [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
实例化模式
| Location | Pattern | Parameters | Frequency |
|---|---|---|---|
| Direct new | config, logger | 3 places |
| Factory | config | 1 place |
| 位置 | 模式 | 参数 | 出现频率 |
|---|---|---|---|
| 直接new | config, logger | 3处 |
| 工厂模式 | config | 1处 |
Dependency Analysis
依赖分析
Dependents (Who calls this)
依赖方(调用当前组件的对象)
| Caller | Method | Context |
|---|---|---|
| | HTTP request handling |
| | Background job |
| 调用方 | 方法 | 上下文 |
|---|---|---|
| | HTTP请求处理 |
| | 后台任务 |
Dependencies (What this calls)
被依赖方(当前组件调用的对象)
| Dependency | Usage | Abstracted? |
|---|---|---|
| Payment processing | No - direct SDK |
| Persistence | Yes - interface |
| 依赖项 | 使用场景 | 是否抽象化 |
|---|---|---|
| 支付处理 | 否 - 直接调用SDK |
| 持久化 | 是 - 基于接口 |
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:
- Quick Wins - Small, low-risk improvements (hours)
- Medium Changes - Meaningful refactoring (days)
- Large Restructuring - Significant architectural changes (weeks)
按从快速优化到复杂重构的顺序排列变更:
- 快速优化 - 小型、低风险的改进(耗时数小时)
- 中型变更 - 有实际意义的重构(耗时数天)
- 大型架构调整 - 重大的架构变更(耗时数周)
For Each Change
每项变更需包含
Provide:
- Problem Statement - What's wrong and why it matters
- Proposed Solution - Concrete approach
- Code Samples - Before and after comparisons
- Impact Analysis - Files affected, risks, dependencies
- Pros and Cons - Honest trade-off assessment
提供:
- 问题陈述 - 存在的问题及其影响
- 解决方案 - 具体实现方案
- 代码示例 - 变更前后的代码对比
- 影响分析 - 受影响的文件、风险、依赖关系
- 优缺点 - 客观的权衡评估
Proposal Output Format
提案输出格式
Write to :
02-proposal.mdmarkdown
undefined写入:
02-proposal.mdmarkdown
undefinedRefactoring 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.tssrc/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.tssrc/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:
- [Quick Win 1] - No dependencies
- [Quick Win 2] - No dependencies
- [Medium Change 1] - Depends on Quick Win 1
- [Large Restructuring] - Depends on Medium Change 1
考虑依赖关系的推荐执行顺序:
- [快速优化1] - 无依赖
- [快速优化2] - 无依赖
- [中型变更1] - 依赖快速优化1
- [大型架构调整] - 依赖中型变更1
Risk Assessment
风险评估
| Change | Risk Level | Mitigation |
|---|---|---|
| [Change 1] | Low | Existing tests cover behavior |
| [Change 2] | Medium | Add integration tests first |
| [Change 3] | High | Feature flag, gradual rollout |
---| 变更 | 风险等级 | 缓解措施 |
|---|---|---|
| [变更1] | 低 | 现有测试覆盖核心行为 |
| [变更2] | 中 | 先新增集成测试 |
| [变更3] | 高 | 使用功能开关,逐步灰度发布 |
---Phase 3: Test Plan
阶段3:测试计划
Goal: Design tests that validate refactoring without regressions.
目标:设计测试用例,在不引入回归问题的前提下验证重构效果。
Analysis Steps
分析步骤
- Audit existing tests - What's already covered?
- Identify gaps - What behavior lacks test coverage?
- Design new tests - Focus on integration over unit tests
- Minimize mocks - Prefer real dependencies when feasible
- 审核现有测试 - 已覆盖哪些场景?
- 识别测试缺口 - 哪些行为缺乏测试覆盖?
- 设计新测试 - 优先关注集成测试而非单元测试
- 最小化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.mdmarkdown
undefined写入:
03-test-plan.mdmarkdown
undefinedTest 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 File | Type | Coverage | Notes |
|---|---|---|---|
| Unit | Core payment flow | Heavy mocking |
| Integration | Happy path only | No error cases |
| 测试文件 | 类型 | 覆盖范围 | 备注 |
|---|---|---|---|
| 单元测试 | 核心支付流程 | 大量使用Mock |
| 集成测试 | 仅 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接口]
| Test | Type | Purpose |
|---|---|---|
| Contract | Verify adapter implements interface correctly |
| Unit | Verify 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();
});
});| 测试 | 类型 | 目的 |
|---|---|---|
| 契约测试 | 验证适配器是否正确实现接口 |
| 单元测试 | 验证服务可与任意网关配合工作 |
新增测试:
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了解测试设计模式