Claude 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に書き換えて。
// 修正前:コールバック地獄
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 });
});
});
});
}
// 修正後: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でCORS設定完全ガイド:クロスオリジン通信の実践解説
Claude Codeを活用したCORS設定の完全ガイド。プリフライトリクエスト、認証付きリクエスト、トラブルシューティングまで実践的に解説します。
Claude Codeで通貨フォーマットを正しく実装する
Claude Codeを使って、多通貨対応・ロケール別フォーマット・為替レート変換など、通貨の表示と処理を正しく実装する方法を解説します。
Claude CodeでDiscord Botを開発する実践ガイド
Claude Codeを活用したDiscord Botの開発方法を解説。discord.js、スラッシュコマンド、ボタン操作、Embed、音声チャンネル連携まで実践的に紹介します。