Claude Codeでコードリファクタリング|安全に品質改善する実践手法

kento_morota 11分で読めます

「技術的負債が溜まっているけれど、リファクタリングに時間を割く余裕がない」。中小企業の開発現場では、こうした悩みを抱えるチームが少なくありません。Claude Codeを活用すれば、リファクタリングにかかる時間を大幅に短縮しながら、安全に品質を改善できます。本記事では、Claude Codeを使ったリファクタリングの実践手法を、テストファーストの安全なアプローチから具体的なパターン、大規模プロジェクトでの活用法まで体系的に解説します。

AIによるリファクタリングのメリットと注意点

Claude Codeを使ったリファクタリングには、手動でのリファクタリングにはない大きなメリットがあります。

メリット

  • 高速な分析:数百ファイルのコードベースでも、構造や依存関係を短時間で把握
  • 一貫した変換:命名規則の統一やパターンの適用を漏れなく実行
  • テストの自動生成:リファクタリング前のテスト作成を高速に行える
  • リスクの低減:変更の影響範囲を事前に分析して提示

注意点

  • 必ずテストで検証する:AIの変更も人間の変更と同様、テストで正しさを担保する必要がある
  • 段階的に進める:一度に大量の変更を行わず、小さな単位で確認しながら進める
  • ビジネスロジックの変更に注意:リファクタリングは振る舞いを変えない変更であることを常に意識する

安全なリファクタリングの進め方:テストファーストアプローチ

リファクタリングで最も重要なのは「振る舞いを変えないこと」です。これを保証するために、テストファーストのアプローチを採用しましょう。

ステップ1:現状の振る舞いをテストで固める

リファクタリング対象のコードに十分なテストがない場合は、まず現在の振る舞いを記録するテスト(特性テスト)を作成します。

> src/services/billingService.tsのcalculateInvoice関数に対して、
  現在の振る舞いを検証するテストを作成して。
  すべての分岐パターン(通常料金、割引適用、税込計算、端数処理)を
  カバーするように。テストは現在のコードの出力をそのまま期待値にして

この時点では、テストがすべてパスすることを確認します。テストが既にあるプロジェクトの場合は、このステップは省略できます。

ステップ2:リファクタリングの方針を確認する

> calculateInvoice関数のリファクタリング方針を提案して。
  現在の問題点(長すぎる関数、責務の混在、テストしにくさ)を分析して、
  どのようなリファクタリングが適切か判断して。
  振る舞いは一切変えないこと

Claude Codeに方針を提案させ、内容を確認してから実際の変更に進みます。拡張思考を活用すると、より深い分析に基づいた提案が得られます。

ステップ3:リファクタリングを実行する

> 提案した方針に沿ってリファクタリングを実行して。
  完了したらテストを実行して、すべてパスすることを確認して

ステップ4:テストを実行して検証する

> テストスイート全体を実行して結果を教えて。
  失敗しているテストがあれば、リファクタリングで振る舞いが
  変わってしまった箇所なので修正が必要

リファクタリングパターン集:Claude Codeへの指示例

ここでは、実際の開発で使えるリファクタリングパターンとClaude Codeへの具体的な指示方法を紹介します。

パターン1:関数の分割(Extract Method)

長すぎる関数を、意味のある単位に分割するリファクタリングです。

> src/controllers/orderController.tsのcreateOrder関数が150行ある。
  以下の責務ごとに関数を分割して:
  1. リクエストのバリデーション
  2. 在庫の確認
  3. 金額の計算
  4. DB保存
  5. メール通知の送信

  各関数は独立してテスト可能な形にすること。
  元の関数はこれらを呼び出すだけのオーケストレーターにして

パターン2:型安全性の強化

any型の除去やユニオン型の導入など、TypeScriptの型安全性を高めるリファクタリングです。

> src/services/ ディレクトリ内のすべてのTypeScriptファイルで、
  any型が使われている箇所を洗い出して。
  それぞれ適切な型定義に置き換えて。
  新しい型が必要な場合はsrc/types/に定義を追加して

パターン3:重複コードの統合(DRY原則)

> src/controllers/ ディレクトリ内で、エラーハンドリングの
  パターンが重複している箇所を特定して。
  共通のエラーハンドリングミドルウェアまたはユーティリティ関数に
  統合して

パターン4:デザインパターンの適用

> src/services/notificationService.tsで、通知手段(メール、Slack、SMS)が
  if-elseチェーンで分岐されている。
  Strategyパターンを適用して、各通知手段を独立したクラスに分離して。
  新しい通知手段を追加する際にメインのコードを変更しなくて済む構造にして

パターン5:非同期処理のモダナイズ

> src/services/ 内でコールバックパターンや.then()チェーンを使っている
  箇所をすべてasync/awaitに書き換えて。
  エラーハンドリングもtry-catchに統一して

大規模コードベースでのリファクタリング戦略

数万行〜数十万行規模のコードベースでは、一度にすべてをリファクタリングすることは現実的ではありません。戦略的なアプローチが必要です。

影響範囲の事前分析

> src/utils/formatDate.tsの関数シグネチャを変更したい。
  この関数を使っているすべてのファイルを一覧表示して、
  変更の影響範囲を教えて

Claude Codeはプロジェクト全体を検索して、影響を受けるファイルを一覧にしてくれます。この情報を基に、変更の優先順位や順序を決めましょう。

ストラングラーフィグパターンの適用

レガシーコードを段階的に新しいコードに置き換える「ストラングラーフィグパターン」は、Claude Codeとの相性が抜群です。

  1. 新しいインターフェースを定義する
  2. 新しい実装を作成し、テストを書く
  3. 既存のコードから新しい実装への切り替えを段階的に行う
  4. 古いコードを削除する
> 現在のUserRepositoryクラスは直接SQLを実行している。
  まず新しいIUserRepositoryインターフェースを定義して、
  次にPrismaを使った新しいUserPrismaRepositoryを実装して。
  既存のUserRepositoryも同じインターフェースを実装するようにして、
  呼び出し元を段階的に切り替えられるようにして

モジュール単位での段階的改善

大規模プロジェクトでは、モジュール(機能単位)ごとにリファクタリングを進めるのが現実的です。

> このプロジェクトのディレクトリ構造を分析して、
  各モジュールの技術的負債の度合い(コードの複雑度、テストカバレッジ、
  重複コードの量)を評価して。優先的にリファクタリングすべき
  モジュールを提案して

リファクタリングのBefore/After実例

具体的なリファクタリングの変更例を示します。

例1:条件分岐の整理

Before

function getShippingCost(order: Order): number {
  if (order.total > 10000) {
    if (order.isPremiumMember) {
      return 0;
    } else {
      return 500;
    }
  } else {
    if (order.isPremiumMember) {
      return 300;
    } else {
      if (order.region === "local") {
        return 600;
      } else {
        return 1200;
      }
    }
  }
}

After

function getShippingCost(order: Order): number {
  if (order.isPremiumMember && order.total > 10000) return 0;
  if (order.isPremiumMember) return 300;
  if (order.total > 10000) return 500;
  return order.region === "local" ? 600 : 1200;
}

ネストの深い条件分岐が、早期リターンを使ったフラットな構造に整理されています。

例2:責務の分離

Before

async function processOrder(orderData: OrderInput) {
  // バリデーション(30行)
  // 在庫確認(20行)
  // 金額計算(40行)
  // DB保存(15行)
  // メール送信(20行)
  // ログ出力(10行)
  // 合計135行の巨大関数
}

After

async function processOrder(orderData: OrderInput) {
  const validatedData = validateOrderInput(orderData);
  await checkInventory(validatedData.items);
  const pricing = calculateOrderPricing(validatedData);
  const order = await saveOrder(validatedData, pricing);
  await sendOrderConfirmation(order);
  logOrderCreated(order);
  return order;
}

各責務が独立した関数に分離され、processOrder関数は処理の流れを示すだけのオーケストレーターになっています。各関数は個別にテスト可能です。

リファクタリングを継続的に行う仕組み

リファクタリングは一度きりのイベントではなく、継続的に行うものです。Claude Codeを使って仕組み化しましょう。

CLAUDE.mdにリファクタリング方針を記載

CLAUDE.mdにコーディング規約やリファクタリングの指針を記載しておくと、新しいコードを書く際にも自動的に品質が維持されます。

# リファクタリング指針
- 関数は50行以内に収める
- ネストは3階層まで
- any型は使用禁止(unknownを使用)
- 新しいファイルを追加する際は、必ずユニットテストも作成する

CI/CDでの品質チェック

自動デプロイのパイプラインに、コード品質チェック(リント、型チェック、テストカバレッジ)を組み込みましょう。Claude Code Actionを使えば、PRに対して自動的にコードレビューを行うことも可能です。

定期的なコード品質レビュー

> プロジェクト全体のコード品質を評価して。
  以下の観点でスコアリングし、改善が必要な箇所を
  優先度順にリストアップして:
  - 関数の複雑度(サイクロマティック複雑度)
  - 重複コード
  - テストカバレッジ
  - 型安全性

月に一度程度、こうした品質レビューを実施すると、技術的負債の蓄積を防げます。

まとめ:AIで技術的負債を計画的に解消しよう

Claude Codeを活用すれば、これまでまとまった時間を確保できずに先送りにしていたリファクタリングを、日々の開発の中で少しずつ進められるようになります。重要なのは以下の3点です。

  • テストファーストで安全性を確保:リファクタリング前にテストを書き、振る舞いが変わっていないことを常に検証
  • 段階的に進める:一度に大量の変更は行わず、小さな単位で確認しながら進める
  • 仕組み化する:CLAUDE.mdやCI/CDで品質を自動的に維持する

Claude Codeの導入がまだの方は、セットアップガイドからスタートしてください。効率的な指示の出し方はプロンプト術の記事で、バグ修正のテクニックはデバッグガイドで詳しく解説しています。AIの力を借りて技術的負債を計画的に解消し、開発チームの生産性と製品の品質を同時に向上させましょう。

#Claude Code#リファクタリング#コード品質
共有:
無料メルマガ

週1回、最新の技術記事をお届け

AI・クラウド・開発の最新記事を毎週月曜にメールでお届けします。登録は無料、いつでも解除できます。

プライバシーポリシーに基づき管理します

AI活用のヒントをお探しですか?お気軽にご相談ください。

まずは話だけ聞いてもらう