🚀 快速安装

复制以下命令并运行,立即安装此 Skill:

npx @anthropic-ai/skills install supercent-io/skills-template/code-refactoring

💡 提示:需要 Node.js 和 NPM

代码重构

何时使用此技能

  • 代码审查:发现复杂或重复的代码时
  • 添加新功能之前:清理现有代码
  • 修复错误之后:消除根本原因
  • 解决技术债务:定期重构

指示

步骤 1:提取方法

重构前(长函数)

function processOrder(order: Order) {
  // 验证
  if (!order.items || order.items.length === 0) {
    throw new Error('订单必须有商品');
  }
  if (!order.customerId) {
    throw new Error('订单必须有客户');
  }

  // 价格计算
  let total = 0;
  for (const item of order.items) {
    total += item.price * item.quantity;
  }
  const tax = total * 0.1;
  const shipping = total > 100 ? 0 : 10;
  const finalTotal = total + tax + shipping;

  // 库存检查
  for (const item of order.items) {
    const product = await db.product.findUnique({ where: { id: item.productId } });
    if (product.stock < item.quantity) {
      throw new Error(`商品 ${product.name} 库存不足`);
    }
  }

  // 创建订单
  const newOrder = await db.order.create({
    data: {
      customerId: order.customerId,
      items: order.items,
      total: finalTotal,
      status: 'pending'
    }
  });

  return newOrder;
}

重构后(提取方法)

async function processOrder(order: Order) {
  validateOrder(order);
  const total = calculateTotal(order);
  await checkInventory(order);
  return await createOrder(order, total);
}

function validateOrder(order: Order) {
  if (!order.items || order.items.length === 0) {
    throw new Error('订单必须有商品');
  }
  if (!order.customerId) {
    throw new Error('订单必须有客户');
  }
}

function calculateTotal(order: Order): number {
  const subtotal = order.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
  const tax = subtotal * 0.1;
  const shipping = subtotal > 100 ? 0 : 10;
  return subtotal + tax + shipping;
}

async function checkInventory(order: Order) {
  for (const item of order.items) {
    const product = await db.product.findUnique({ where: { id: item.productId } });
    if (product.stock < item.quantity) {
      throw new Error(`商品 ${product.name} 库存不足`);
    }
  }
}

async function createOrder(order: Order, total: number) {
  return await db.order.create({
    data: {
      customerId: order.customerId,
      items: order.items,
      total,
      status: 'pending'
    }
  });
}

步骤 2:消除重复

重构前(重复)

async function getActiveUsers() {
  return await db.user.findMany({
    where: { status: 'active', deletedAt: null },
    select: { id: true, name: true, email: true }
  });
}

async function getActivePremiumUsers() {
  return await db.user.findMany({
    where: { status: 'active', deletedAt: null, plan: 'premium' },
    select: { id: true, name: true, email: true }
  });
}

重构后(提取公共逻辑)

type UserFilter = {
  plan?: string;
};

async function getActiveUsers(filter: UserFilter = {}) {
  return await db.user.findMany({
    where: {
      status: 'active',
      deletedAt: null,
      ...filter
    },
    select: { id: true, name: true, email: true }
  });
}

// 使用
const allActiveUsers = await getActiveUsers();
const premiumUsers = await getActiveUsers({ plan: 'premium' });

步骤 3:用多态替换条件判断

重构前(长 if-else)

class PaymentProcessor {
  process(payment: Payment) {
    if (payment.method === 'credit_card') {
      // 信用卡处理
      const cardToken = this.tokenizeCard(payment.card);
      const charge = this.chargeCreditCard(cardToken, payment.amount);
      return charge;
    } else if (payment.method === 'paypal') {
      // PayPal处理
      const paypalOrder = this.createPayPalOrder(payment.amount);
      const approval = this.getPayPalApproval(paypalOrder);
      return approval;
    } else if (payment.method === 'bank_transfer') {
      // 银行转账处理
      const transfer = this.initiateBankTransfer(payment.account, payment.amount);
      return transfer;
    }
  }
}

重构后(多态)

interface PaymentMethod {
  process(payment: Payment): Promise<PaymentResult>;
}

class CreditCardPayment implements PaymentMethod {
  async process(payment: Payment): Promise<PaymentResult> {
    const cardToken = await this.tokenizeCard(payment.card);
    return await this.chargeCreditCard(cardToken, payment.amount);
  }
}

class PayPalPayment implements PaymentMethod {
  async process(payment: Payment): Promise<PaymentResult> {
    const order = await this.createPayPalOrder(payment.amount);
    return await this.getPayPalApproval(order);
  }
}

class BankTransferPayment implements PaymentMethod {
  async process(payment: Payment): Promise<PaymentResult> {
    return await this.initiateBankTransfer(payment.account, payment.amount);
  }
}

class PaymentProcessor {
  private methods: Map<string, PaymentMethod> = new Map([
    ['credit_card', new CreditCardPayment()],
    ['paypal', new PayPalPayment()],
    ['bank_transfer', new BankTransferPayment()]
  ]);

  async process(payment: Payment): Promise<PaymentResult> {
    const method = this.methods.get(payment.method);
    if (!method) {
      throw new Error(`未知的支付方式:${payment.method}`);
    }
    return await method.process(payment);
  }
}

步骤 4:引入参数对象

重构前(参数过多)

function createUser(
  name: string,
  email: string,
  password: string,
  age: number,
  country: string,
  city: string,
  postalCode: string,
  phoneNumber: string
) {
  // ...
}

重构后(组合成对象)

interface UserProfile {
  name: string;
  email: string;
  password: string;
  age: number;
}

interface Address {
  country: string;
  city: string;
  postalCode: string;
}

interface CreateUserParams {
  profile: UserProfile;
  address: Address;
  phoneNumber: string;
}

function createUser(params: CreateUserParams) {
  const { profile, address, phoneNumber } = params;
  // ...
}

// 使用
createUser({
  profile: { name: '张三', email: 'zhangsan@example.com', password: 'xxx', age: 30 },
  address: { country: '中国', city: '北京', postalCode: '100000' },
  phoneNumber: '+861234567890'
});

步骤 5:应用 SOLID 原则

单一职责原则

// ❌ 反面示例:多个职责
class User {
  constructor(public name: string, public email: string) {}

  save() {
    // 保存到数据库
  }

  sendEmail(subject: string, body: string) {
    // 发送邮件
  }

  generateReport() {
    // 生成报告
  }
}

// ✅ 良好示例:职责分离
class User {
  constructor(public name: string, public email: string) {}
}

class UserRepository {
  save(user: User) {
    // 保存到数据库
  }
}

class EmailService {
  send(to: string, subject: string, body: string) {
    // 发送邮件
  }
}

class UserReportGenerator {
  generate(user: User) {
    // 生成报告
  }
}

输出格式

重构检查清单

- [ ] 函数只做一件事(单一职责原则)
- [ ] 函数名清晰描述其功能
- [ ] 函数不超过 20 行(指导原则)
- [ ] 参数不超过 3 个
- [ ] 无重复代码(DRY)
- [ ] 条件嵌套不超过 2 层
- [ ] 无魔法数字(提取为常量)
- [ ] 无需注释即可理解(自文档化)

约束条件

强制性规则(必须遵守)

  1. 测试先行:重构前先编写测试
  2. 小步快跑:一次只改一个方面
  3. 行为保留:无功能性变更

禁止事项(不得违反)

  1. 同时处理多项任务:不得同时进行重构和添加功能
  2. 无测试重构:存在回归风险

最佳实践

  1. 童子军规则:让代码比你发现时更干净
  2. 重构时机:红-绿-重构(测试驱动开发)
  3. 渐进式改进:追求一致性而非完美
  4. 行为保留:重构不涉及功能变更
  5. 小提交:按聚焦单元提交

行为验证(代码简化器集成)

步骤 A:理解当前行为

在重构前充分理解当前行为:

## 行为分析

### 输入
- [列出输入参数]
- [类型和约束]

### 输出
- [返回值]
- [副作用]

### 不变量
- [必须始终成立的条件]
- [边界情况]

### 依赖项
- [外部依赖]
- [状态依赖]

步骤 B:重构后验证

# 1. 运行测试
npm test -- --coverage

# 2. 类型检查
npx tsc --noEmit

# 3. 代码风格检查
npm run lint

# 4. 与先前行为对比(快照测试)
npm test -- --updateSnapshot

步骤 C:记录更改

## 重构总结

### 所做的更改
1. [更改 1]: [原因]
2. [更改 2]: [原因]

### 行为保留情况
- [x] 相同输入 → 相同输出
- [x] 相同副作用
- [x] 相同错误处理

### 风险与后续工作
- [潜在风险]
- [后续任务]

### 测试状态
- [ ] 单元测试:通过
- [ ] 集成测试:通过
- [ ] 端到端测试:通过

故障排除

问题:重构后测试失败

原因:发生了行为变更
解决方案:回退并隔离更改,然后重试

问题:代码仍然复杂

原因:一个函数中混合了多个职责
解决方案:提取成边界清晰的小单元

问题:性能下降

原因:引入了低效的抽象
解决方案:分析性能并优化热点路径


多智能体工作流

验证与回顾

  • 第一轮(协调者):验证行为保留清单
  • 第二轮(分析师):复杂度和重复性分析
  • 第三轮(执行者):测试或静态分析验证

智能体角色

智能体 角色
Claude 重构计划、代码转换
Gemini 大规模代码库分析、模式检测
Codex 测试执行、构建验证

工作流示例

# 1. Gemini:代码库分析
ask-gemini "@src/ 提取高复杂度函数列表"

# 2. Claude:重构计划与执行
# 基于 IMPLEMENTATION_PLAN.md 工作

# 3. Codex:验证
codex-cli shell "npm test && npm run lint"

参考资料

元数据

版本

  • 当前版本:1.0.0
  • 最后更新:2025-01-01
  • 兼容平台:Claude, ChatGPT, Gemini

相关技能

标签

#重构 #代码质量 #DRY #SOLID #设计模式 #整洁代码

示例

示例 1:基本用法

示例 2:高级用法

📄 原始文档

完整文档(英文):

https://skills.sh/supercent-io/skills-template/code-refactoring

💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。