refactoring-specialist

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Refactoring Specialist

重构专家

Expert guidance on refactoring code to improve structure, readability, and maintainability while preserving functionality.
提供专业的代码重构指导,在保留功能的同时改进代码结构、可读性和可维护性。

When This Skill Activates

触发场景

Activates when you:
  • Ask to refactor code
  • Request cleanup or improvement
  • Mention "technical debt" or "code smell"
  • Want to improve code quality
当你有以下需求时,该技能会激活:
  • 请求代码重构
  • 要求清理或改进代码
  • 提及“技术债务”或“代码坏味道”
  • 希望提升代码质量

Refactoring Principles

重构原则

  1. Preserve Behavior: Refactoring must not change external behavior
  2. Small Steps: Make small, incremental changes
  3. Test Coverage: Ensure tests pass before and after
  4. Commit Often: Commit after each successful refactoring
  1. 保留行为:重构不得改变外部功能表现
  2. 小步迭代:进行微小、渐进式的修改
  3. 测试覆盖:确保重构前后测试均通过
  4. 频繁提交:每次成功重构后提交代码

Code Smells to Address

需要处理的代码坏味道

1. Long Method

1. 过长方法

Symptom: Function > 20-30 lines
Refactoring: Extract Method
typescript
// Before:
function processOrder(order) {
  // 50 lines of code
}

// After:
function processOrder(order) {
  validateOrder(order);
  calculateTotals(order);
  saveOrder(order);
  sendConfirmation(order);
}
特征:函数代码超过20-30行
重构方案:提取方法
typescript
// 重构前:
function processOrder(order) {
  // 50行代码
}

// 重构后:
function processOrder(order) {
  validateOrder(order);
  calculateTotals(order);
  saveOrder(order);
  sendConfirmation(order);
}

2. Duplicate Code

2. 重复代码

Symptom: Similar code in multiple places
Refactoring: Extract Method / Template Method
typescript
// Before:
class UserService {
  async validateEmail(email) {
    if (!email || !email.includes('@')) return false;
    const domain = email.split('@')[1];
    return domain.length > 0;
  }
}
class AdminService {
  async validateEmail(email) {
    if (!email || !email.includes('@')) return false;
    const domain = email.split('@')[1];
    return domain.length > 0;
  }
}

// After:
class EmailValidator {
  async validate(email) {
    if (!email || !email.includes('@')) return false;
    return email.split('@')[1].length > 0;
  }
}
特征:多个位置出现相似代码
重构方案:提取方法 / 模板方法
typescript
// 重构前:
class UserService {
  async validateEmail(email) {
    if (!email || !email.includes('@')) return false;
    const domain = email.split('@')[1];
    return domain.length > 0;
  }
}
class AdminService {
  async validateEmail(email) {
    if (!email || !email.includes('@')) return false;
    const domain = email.split('@')[1];
    return domain.length > 0;
  }
}

// 重构后:
class EmailValidator {
  async validate(email) {
    if (!email || !email.includes('@')) return false;
    return email.split('@')[1].length > 0;
  }
}

3. Large Class

3. 过大类

Symptom: Class doing too many things
Refactoring: Extract Class
typescript
// Before:
class User {
  // Authentication
  // Profile management
  // Notifications
  // Reporting
}

// After:
class User { /* Core user data */ }
class UserAuth { /* Authentication */ }
class UserProfile { /* Profile management */ }
class UserNotifier { /* Notifications */ }
特征:一个类承担过多职责
重构方案:提取类
typescript
// 重构前:
class User {
  // 认证功能
  // 资料管理
  // 通知功能
  // 报表功能
}

// 重构后:
class User { /* 核心用户数据 */ }
class UserAuth { /* 认证功能 */ }
class UserProfile { /* 资料管理 */ }
class UserNotifier { /* 通知功能 */ }

4. Long Parameter List

4. 过长参数列表

Symptom: Function with 4+ parameters
Refactoring: Introduce Parameter Object
typescript
// Before:
function createUser(name, email, age, address, phone, role) { ... }

// After:
function createUser(user: UserData) { ... }

interface UserData {
  name: string;
  email: string;
  age: number;
  address: string;
  phone: string;
  role: string;
}
特征:函数参数数量超过4个
重构方案:引入参数对象
typescript
// 重构前:
function createUser(name, email, age, address, phone, role) { ... }

// 重构后:
function createUser(user: UserData) { ... }

interface UserData {
  name: string;
  email: string;
  age: number;
  address: string;
  phone: string;
  role: string;
}

5. Feature Envy

5. 特性依恋

Symptom: Method uses more data from other classes
Refactoring: Move Method
typescript
// Before:
class Order {
  calculatePrice(customer) {
    const discount = customer.getDiscountLevel();
    // ...
  }
}

// After:
class Customer {
  calculatePriceForOrder(order) {
    const discount = this.discountLevel;
    // ...
  }
}
特征:方法更多依赖其他类的数据
重构方案:移动方法
typescript
// 重构前:
class Order {
  calculatePrice(customer) {
    const discount = customer.getDiscountLevel();
    // ...
  }
}

// 重构后:
class Customer {
  calculatePriceForOrder(order) {
    const discount = this.discountLevel;
    // ...
  }
}

6. Data Clumps

6. 数据泥团

Symptom: Same data appearing together
Refactoring: Extract Value Object
typescript
// Before:
function drawShape(x, y, width, height) { ... }
function moveShape(x, y, width, height, dx, dy) { ... }

// After:
class Rectangle {
  constructor(x, y, width, height) { ... }
}
function drawShape(rect: Rectangle) { ... }
特征:相同的数据组合重复出现
重构方案:提取值对象
typescript
// 重构前:
function drawShape(x, y, width, height) { ... }
function moveShape(x, y, width, height, dx, dy) { ... }

// 重构后:
class Rectangle {
  constructor(x, y, width, height) { ... }
}
function drawShape(rect: Rectangle) { ... }

7. Primitive Obsession

7. 基本类型偏执

Symptom: Using primitives instead of small objects
Refactoring: Replace Primitive with Object
typescript
// Before:
function createUser(name, email, phone) { ... }

// After:
class Email {
  constructor(value) {
    if (!this.isValid(value)) throw new Error('Invalid email');
    this.value = value;
  }
  // ...
}
特征:使用基本类型而非小型对象
重构方案:用对象替换基本类型
typescript
// 重构前:
function createUser(name, email, phone) { ... }

// 重构后:
class Email {
  constructor(value) {
    if (!this.isValid(value)) throw new Error('Invalid email');
    this.value = value;
  }
  // ...
}

8. Switch Statements

8. 分支语句

Symptom: Large switch on type
Refactoring: Replace Conditional with Polymorphism
typescript
// Before:
function calculatePay(employee) {
  switch (employee.type) {
    case 'engineer': return employee.salary * 1.2;
    case 'manager': return employee.salary * 1.5;
    case 'sales': return employee.salary * 1.1;
  }
}

// After:
interface Employee {
  calculatePay(): number;
}
class Engineer implements Employee {
  calculatePay() { return this.salary * 1.2; }
}
特征:基于类型的大型switch分支
重构方案:用多态替代条件判断
typescript
// 重构前:
function calculatePay(employee) {
  switch (employee.type) {
    case 'engineer': return employee.salary * 1.2;
    case 'manager': return employee.salary * 1.5;
    case 'sales': return employee.salary * 1.1;
  }
}

// 重构后:
interface Employee {
  calculatePay(): number;
}
class Engineer implements Employee {
  calculatePay() { return this.salary * 1.2; }
}

9. Temporary Field

9. 临时字段

Symptom: Variables only used in certain scenarios
Refactoring: Extract Class
typescript
// Before:
class User {
  calculateRefund() {
    this.tempRefundAmount = 0;
    // complex calculation
    return this.tempRefundAmount;
  }
}

// After:
class RefundCalculator {
  calculate(user) {
    // ...
  }
}
特征:变量仅在特定场景下使用
重构方案:提取类
typescript
// 重构前:
class User {
  calculateRefund() {
    this.tempRefundAmount = 0;
    // 复杂计算逻辑
    return this.tempRefundAmount;
  }
}

// 重构后:
class RefundCalculator {
  calculate(user) {
    // ...
  }
}

10. Comments

10. 过多注释

Symptom: Code needs extensive comments
Refactoring: Extract Method with clear name
typescript
// Before:
// Calculate the total price including discounts
// and tax based on user location
function calc(u, i) {
  let t = 0;
  // discount logic
  if (u.vip) t *= 0.9;
  // tax logic
  if (u.state === 'CA') t *= 1.08;
  return t;
}

// After:
function calculateTotalPrice(user: User, items: Item[]): number {
  let total = items.sum(i => i.price);
  if (user.isVIP) {
    total = applyVIPDiscount(total);
  }
  return applyTax(total, user.state);
}
特征:代码需要大量注释才能理解
重构方案:提取具有清晰命名的方法
typescript
// 重构前:
// 计算包含折扣和基于用户所在地的税费的总价
function calc(u, i) {
  let t = 0;
  // 折扣逻辑
  if (u.vip) t *= 0.9;
  // 税费逻辑
  if (u.state === 'CA') t *= 1.08;
  return t;
}

// 重构后:
function calculateTotalPrice(user: User, items: Item[]): number {
  let total = items.sum(i => i.price);
  if (user.isVIP) {
    total = applyVIPDiscount(total);
  }
  return applyTax(total, user.state);
}

Refactoring Steps

重构步骤

  1. Identify the smell - What makes this code hard to work with?
  2. Determine the refactoring - Which technique applies?
  3. Ensure tests pass - Green before starting
  4. Apply the refactoring - Make the change
  5. Run tests - Verify behavior unchanged
  6. Commit - Small, atomic commits
  1. 识别问题:找出代码难以维护的原因
  2. 选择方案:确定适用的重构技巧
  3. 验证测试:确保开始前测试全部通过
  4. 执行重构:进行代码修改
  5. 运行测试:验证功能未发生变化
  6. 提交代码:进行小而独立的提交

Safe Refactoring Practices

安全重构实践

  • Use your IDE's refactoring tools (Rename, Extract, Move)
  • Run tests frequently (after each change)
  • Keep commits small and focused
  • Write a descriptive commit message
  • Consider code reviews for complex refactorings
  • 使用IDE的重构工具(重命名、提取、移动)
  • 频繁运行测试(每次修改后)
  • 保持提交内容小而聚焦
  • 编写描述性的提交信息
  • 复杂重构可考虑代码评审

Before Refactoring

重构前检查清单

  • Tests are passing
  • I understand what the code does
  • I have identified the specific code smell
  • I know which refactoring to apply
  • I have a rollback plan
  • 测试全部通过
  • 我理解代码的功能
  • 已明确识别代码坏味道
  • 确定了要使用的重构方法
  • 有回滚方案

After Refactoring

重构后检查清单

  • Tests still pass
  • Code is more readable
  • Code is easier to maintain
  • No new code smells introduced
  • Documentation updated if needed
  • 测试仍全部通过
  • 代码可读性提升
  • 代码更易于维护
  • 未引入新的代码坏味道
  • 必要时更新了文档

References

参考资料

  • references/smells.md
    - Complete code smell catalog
  • references/techniques.md
    - Refactoring techniques
  • references/checklist.md
    - Refactoring checklist
  • references/smells.md
    - 完整的代码坏味道目录
  • references/techniques.md
    - 重构技巧手册
  • references/checklist.md
    - 重构检查清单