Use Cases

Safely Modernizing Legacy Code:Claude Code 实战指南

了解safely modernizing legacy code:Claude Code 实战. 包含实用代码示例。

レガシーコードとの戦い方

测试がなく、文档も古く、誰も触りたくないコード。Claude Code そんなレガシーコードの理解から改善まで強力にサポートします。

ステップ1:コードの理解

まず让 Claude Codeコードを分析させましょう。

> src/legacy/ 以下コードを分析して。
> 每个文件の責務、依存関係、数据フローを説明して。
> 問題点と改善の優先順位も提案して。

Claude Code コード全体を読んだ上で、構造の説明と改善計画を提示します。

ステップ2:测试の添加

改修前に测试を書いて、現在の振る舞いを保証します。

> src/legacy/orderProcessor.js の現在の振る舞いを
> 保証する测试创建。
> 函数の入输出を分析して、正常系・異常系をカバーして。
> まだコードは更改しないで。
// レガシーコードの振る舞いを保証する测试
import { processOrder } from "../legacy/orderProcessor";

describe("processOrder - 既存の振る舞いを保証", () => {
  it("正常な注文を処理できる", () => {
    const order = {
      items: [{ id: "A1", qty: 2, price: 1000 }],
      customer: { id: "C1", type: "regular" },
    };
    const result = processOrder(order);
    expect(result.total).toBe(2000);
    expect(result.status).toBe("confirmed");
  });

  it("空の注文でエラーを返す", () => {
    const order = { items: [], customer: { id: "C1", type: "regular" } };
    const result = processOrder(order);
    expect(result.status).toBe("error");
    expect(result.message).toContain("items");
  });

  it("VIP顧客に割引を適用する", () => {
    const order = {
      items: [{ id: "A1", qty: 1, price: 10000 }],
      customer: { id: "C2", type: "vip" },
    };
    const result = processOrder(order);
    expect(result.total).toBe(9000); // 10% off
  });
});

ステップ3:段階的重构

测试が通ることを确认しながら、少しずつ改善します。

> 测试を維持しながら、orderProcessor.jsを以下方針で
> 重构して:
> 1. TypeScriptに変換
> 2. 类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类型定義を添加
> 3. 1函数1責務に分割
> 4. 每个更改後に测试が通ることを确认
// 重构後の構造
// orderProcessor.ts - メイン処理
export function processOrder(order: OrderInput): OrderResult {
  const validation = validateOrder(order);
  if (!validation.valid) {
    return { status: "error", message: validation.message };
  }

  const subtotal = calculateSubtotal(order.items);
  const discount = calculateDiscount(subtotal, order.customer);
  const total = subtotal - discount;

  return {
    status: "confirmed",
    total,
    items: order.items,
    discount,
  };
}

// validators.ts - 验证
export function validateOrder(order: OrderInput): ValidationResult {
  if (!order.items || order.items.length === 0) {
    return { valid: false, message: "items is required" };
  }
  return { valid: true };
}

// calculators.ts - 計算ロジック
export function calculateSubtotal(items: OrderItem[]): number {
  return items.reduce((sum, item) => sum + item.price * item.qty, 0);
}

export function calculateDiscount(subtotal: number, customer: Customer): number {
  if (customer.type === "vip") {
    return subtotal * 0.1;
  }
  return 0;
}

ステップ4:JavaScriptからTypeScriptへの移行

> src/legacy/ 以下JS文件をすべてTypeScriptに変換して。
> 1. まず.jsを.tsにリネーム
> 2. any类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类型で类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类型チェックを通す
> 3. anyを合适的类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类类型に置き換える
> 4. 每个ステップで测试が通ることを确认

回调地獄の解消

> 回调ベースの异步処理を
> async/awaitに書き換えて。
// Before fix:回调地獄
function fetchUserData(userId, callback) {
  db.getUser(userId, (err, user) => {
    if (err) return callback(err);
    db.getPosts(user.id, (err, posts) => {
      if (err) return callback(err);
      db.getComments(posts[0].id, (err, comments) => {
        if (err) return callback(err);
        callback(null, { user, posts, comments });
      });
    });
  });
}

// After fix:async/await
async function fetchUserData(userId: string): Promise<UserData> {
  const user = await db.getUser(userId);
  const posts = await db.getPosts(user.id);
  const comments = posts.length > 0
    ? await db.getComments(posts[0].id)
    : [];
  return { user, posts, comments };
}

依存関係の更新

> package.jsonの依存包で古いものを特定して。
> メジャーバージョンが2つ以上古いものを恢复ップ。
> 更新時のbreaking changesも調べて。

重构の具体的パターンは重构自动化指南を、测试添加の戦略はTDDとClaude Codeの相性。段階的な改善で文档も更新する方法は文档自動生成也请一并查看。

总结

レガシーコード改善の鍵は「测试で安全網を張ってから少しずつ変える」ことです。Claude Code 这个进程を大幅に效率化します。一度にすべてを変えようとせず、段階的に進めましょう。

レガシーコード改善の名著『Working Effectively with Legacy Code』の考え方とClaude Code 非常に相性が良いです。Claude Code 的详细信息请参阅Anthropic官方文档

#Claude Code #legacy code #リファクタリング #技術的負債 #モダナイゼーション