mcpField
C
code-refactoring

code-refactoring

github.com/moizibnyousaf开发1.2k585 次安装5 周前更新
代码仓库

关于 code-refactoring

这是一项面向开发者的代码重构技能,帮助改善代码结构并保持行为不变。它整理常见代码异味和重构技巧,并建议通过测试保障、小步修改和逐次验证来实施重构。

主要功能

  1. 01何时重构的指导
  2. 02常见代码异味示例
  3. 03改善代码结构的重构技巧
  4. 04测试保障检查清单
  5. 05小步修改并反复运行测试

适用场景

  1. 01拆分过长的方法
  2. 02简化嵌套条件判断
  3. 03用值对象替代原始值
  4. 04在代码审查中安全重构

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/moizibnyousaf/ai-agent-skills --skill code-refactoring

安装后在 Claude Code 中输入/code-refactoring确认已加载。

详细介绍

代码重构

重构原则

何时重构
  • 添加新功能之前(先让改动更容易,再轻松地进行改动)
  • 测试通过之后(红-绿-重构)
  • 发现代码异味时
  • 根据代码审查反馈进行重构时
何时不应重构
  • 没有测试覆盖代码时
  • 截止时间紧迫且没有安全保障时
  • 即将被替换的代码
  • 不理解代码作用时

常见代码异味

过长的方法
// BEFORE: Method doing too much
function processOrder(order: Order) {
  // 100 lines of validation, calculation, notification, logging...
}

// AFTER: Extract into focused methods
function processOrder(order: Order) {
  validateOrder(order);
  const total = calculateTotal(order);
  saveOrder(order, total);
  notifyCustomer(order);
}
过深嵌套的条件语句
// BEFORE: Arrow code
function getDiscount(user: User, order: Order) {
  if (user) {
    if (user.isPremium) {
      if (order.total > 100) {
        if (order.items.length > 5) {
          return 0.2;
        }
      }
    }
  }
  return 0;
}

// AFTER: Early returns (guard clauses)
function getDiscount(user: User, order: Order) {
  if (!user) return 0;
  if (!user.isPremium) return 0;
  if (order.total <= 100) return 0;
  if (order.items.length <= 5) return 0;
  return 0.2;
}
基本类型偏执
// BEFORE: Primitives everywhere
function createUser(name: string, email: string, phone: string) {
  if (!email.includes('@')) throw new Error('Invalid email');
  // more validation...
}

// AFTER: Value objects
class Email {
  constructor(private value: string) {
    if (!value.includes('@')) throw new Error('Invalid email');
  }
  toString() { return this.value; }
}

function createUser(name: string, email: Email, phone: Phone) {
  // Email is already validated
}
过度依赖其他类的特性
// BEFORE: Method uses another object's data extensively
function calculateShipping(order: Order) {
  const address = order.customer.address;
  const weight = order.items.reduce((sum, i) => sum + i.weight, 0);
  const distance = calculateDistance(address.zip);
  return weight * distance * 0.01;
}

// AFTER: Move method to where the data is
class Order {
  calculateShipping() {
    return this.totalWeight * this.customer.shippingDistance * 0.01;
  }
}

重构技巧

提取方法
// Identify a code block that does one thing
// Move it to a new method with a descriptive name
// Replace original code with method call

function printReport(data: ReportData) {
  // Extract this block...
  const header = `Report: ${data.title}\nDate: ${data.date}\n${'='.repeat(40)}`;
  console.log(header);

  // ...into a method
  printHeader(data);
}
用多态替换条件语句
// BEFORE: Switch on type
function getArea(shape: Shape) {
  switch (shape.type) {
    case 'circle': return Math.PI * shape.radius ** 2;
    case 'rectangle': return shape.width * shape.height;
    case 'triangle': return shape.base * shape.height / 2;
  }
}

// AFTER: Polymorphic classes
interface Shape {
  getArea(): number;
}

class Circle implements Shape {
  constructor(private radius: number) {}
  getArea() { return Math.PI * this.radius ** 2; }
}

class Rectangle implements Shape {
  constructor(private width: number, private height: number) {}
  getArea() { return this.width * this.height; }
}
引入参数对象
// BEFORE: Too many parameters
function searchProducts(
  query: string,
  minPrice: number,
  maxPrice: number,
  category: string,
  inStock: boolean,
  sortBy: string,
  sortOrder: string
) { ... }

// AFTER: Parameter object
interface SearchParams {
  query: string;
  priceRange: { min: number; max: number };
  category?: string;
  inStock?: boolean;
  sort?: { by: string; order: 'asc' | 'desc' };
}

function searchProducts(params: SearchParams) { ... }
用常量替换魔法数字
// BEFORE
if (user.age >= 18 && order.total >= 50) {
  applyDiscount(order, 0.1);
}

// AFTER
const MINIMUM_AGE = 18;
const DISCOUNT_THRESHOLD = 50;
const STANDARD_DISCOUNT = 0.1;

if (user.age >= MINIMUM_AGE && order.total >= DISCOUNT_THRESHOLD) {
  applyDiscount(order, STANDARD_DISCOUNT);
}

安全的重构流程

  1. 确保存在测试 - 如果没有测试,就编写测试
  2. 进行小幅改动 - 每次只做一项重构
  3. 每次改动后运行测试 - 立即发现回归问题
  4. 频繁提交 - 出现问题时便于回滚
  5. 检查差异 - 确保行为没有改变

重构检查清单

  • 开始前测试通过
  • 每项改动都小而专注
  • 每次改动后测试通过
  • 行为没有改变(仅结构发生变化)
  • 代码比之前更易读
  • 提交信息说明了重构内容

评论

支持 Markdown