Claude Code リファクタリング完全ガイド|4フェーズワークフロー・Strangler Figパターン・worktree並列マイグレーション・影響範囲調査の実践手法

Claude Code リファクタリング完全ガイド|4フェーズワークフロー・Strangler Figパターン・worktree並列マイグレーション・影響範囲調査の実践手法 AI開発

リファクタリングはClaude Codeが最も得意とする作業の一つです。しかし「一気に全部直して」と頼むと、影響範囲の把握不足による動作バグや、コンテキストが汚染されて途中で迷子になる問題が起きがちです。

この記事では、Plan Modeを使った4フェーズワークフローを軸に、Strangler Figパターンによる段階的リファクタリング・worktreeを活用した並列マイグレーション・サブエージェントによる影響範囲調査まで、大規模リファクタリングを安全に進める実践手法を解説します。Plan Modeの基本はPlan Mode完全ガイドを、worktreeの基本はWorktree完全ガイドを参照してください。

スポンサーリンク

リファクタリングの4フェーズワークフロー

Anthropicが推奨するリファクタリングの基本フローは探索(Explore)→ 計画(Plan)→ 実装(Implement)→ 検証(Verify)の4段階です。探索と計画はPlan Mode、実装は通常モードで行うことで「考えながら手を動かす」という危険な状態を防げます。

フェーズ モード 主な作業
探索 Plan Mode(Shift+Tab) 変更対象のコードを読み、依存関係・影響範囲を把握する
計画 Plan Mode 実装ステップを具体化。順序・リスク・テスト方針を決める
実装 通常モード 計画に従ってコードを変更する
検証 通常モード テスト実行・lintチェック・動作確認。失敗があれば修正してループ

フェーズ1: 探索(Explore)

探索フェーズのプロンプト例
# Plan Modeに切り替えてから(Shift+Tab)
"Read src/components/UserDashboard.tsx and understand:
- What data does it fetch and from where?
- What child components does it render?
- Are there any performance issues?
Do NOT make any changes yet."

探索フェーズでは「変更しないでください」を明示することが重要です。Claude Codeは親切心から変更を先行することがあるため、Plan Mode中であることと合わせて明示的に制約を伝えます。

フェーズ2: 計画(Plan)

計画フェーズのプロンプト例
# 探索結果をもとに計画を立てる
"Based on your analysis, create a refactoring plan for UserDashboard.tsx.
The goal is to split it into smaller components under 200 lines each.
Include:
1. What components to extract and their boundaries
2. Props and data flow between components
3. Order of changes to minimize breaking changes
4. Tests to run at each step"
Ctrl+G でプランをエディタで直接編集
計画が生成されたら Ctrl+G を押すと計画内容がエディタで開きます。追記・修正してから実装に進むことで、Claudeとの認識ズレによる手戻りを減らせます。

フェーズ3: 実装(Implement)

実装フェーズへの移行
# Plan Modeを解除してから(Shift+Tab で通常モードへ)
"Implement the refactoring plan.
Start with extracting StatsSection as the first component.
After each component extraction, run npm test to verify nothing broke."

フェーズ4: 検証(Verify)

実装が終わったら必ず検証を指示します。見た目が正しいコードが実際には動かないというミスを防ぐには、具体的な検証コマンドをセットで依頼するのが効果的です。

検証フェーズのプロンプト例
"Run the following checks and fix any failures:
1. npm test -- --coverage (all tests must pass)
2. npm run lint
3. npm run type-check
4. Start the dev server and check the dashboard renders correctly.
Do not mark as complete until all checks pass."

影響範囲調査:サブエージェントで安全にスコープを把握する

リファクタリング前の影響範囲調査は、サブエージェントに委譲するのが最も効率的です。調査のためにメインコンテキストを大量消費せずに済み、実装フェーズで使えるコンテキストを温存できます。サブエージェントの詳細はSubagents完全ガイドを参照してください。

影響範囲調査をサブエージェントに委譲
# 変更前に影響範囲を把握する
claude "Use subagents to investigate the impact of refactoring the AuthService class:

1. Find all files that import or instantiate AuthService
2. Find all tests that directly test AuthService
3. Check if AuthService is referenced in any documentation or config files

Report the complete impact scope with file paths before we start making changes."
並列調査でコンポーネント間の依存を把握
# 複数箇所を並列に調査してから比較
claude "Use parallel subagents to investigate:
1. How the frontend API client handles authentication errors (src/api/)
2. How the backend generates error responses for auth failures (src/server/auth/)
3. What existing auth error tests cover (tests/)

Report where the implementations align and where they diverge."

Strangler Figパターン:稼働中システムを安全に置き換える

Strangler Figパターンは既存システムを動かしながら少しずつ新実装に置き換えていく手法です。レガシーコードの一括リプレースより安全で、Claude Codeとの相性も抜群です。「1ファイル(1機能)ずつ新実装に切り替え、テストが通ったら旧実装を削除する」という単純な繰り返しをClaudeに実行させられます。

Strangler Figパターンの実装ステップ

  1. 新旧コードを共存させるための「ファサード」を作成する
  2. ファサードが旧コードに委譲した状態でテストがすべて通ることを確認する
  3. 機能単位で新実装を作成し、ファサードの委譲先を新実装に切り替える
  4. テストが通ったら旧コードを削除する
  5. 2〜4を繰り返す
Strangler Figパターンの例(TypeScript)
// フェーズ1: ファサードを作成(旧実装に委譲)
// auth-facade.ts
export class AuthFacade {
  constructor(private legacy: LegacyAuthService) {}

  async login(email: string, password: string) {
    // まず旧実装に委譲
    return this.legacy.authenticate(email, password);
  }
}

// フェーズ2: 新実装を作成してファサードを切り替え
// auth-facade.ts(更新後)
export class AuthFacade {
  constructor(
    private legacy: LegacyAuthService,
    private newAuth: NewAuthService,
    private useNew = false,  // Feature Flagで制御
  ) {}

  async login(email: string, password: string) {
    if (this.useNew) {
      return this.newAuth.login(email, password);  // 新実装
    }
    return this.legacy.authenticate(email, password);  // 旧実装
  }
}

// フェーズ3: テスト通過後、旧実装を削除してファサードも廃止
Strangler FigパターンのClaude Codeプロンプト例
# ステップ1: ファサード作成
claude "Create an AuthFacade class that wraps LegacyAuthService.
The facade should have the same interface as LegacyAuthService
but delegate all calls to it. This will be our Strangler Fig entry point."

# ステップ2: 既存の呼び出し箇所をファサードに切り替え
claude "Find all places that use LegacyAuthService directly and update them
to use AuthFacade instead. Run the tests after each file change."

# ステップ3: 1メソッドずつ新実装に切り替え
claude "Implement the login() method in NewAuthService.
Switch AuthFacade.login() to use NewAuthService.
Run the login-related tests and fix any failures before continuing."

JS→TSマイグレーション:worktreeで並列化する

JavaScriptからTypeScriptへの移行のように、多数のファイルを変換するマイグレーションにはworktreeを使った並列化が有効です。複数のworktreeブランチに担当ファイルを分割して同時に変換し、最後にマージすることで単純な順次変換より大幅に時間を短縮できます。

worktreeを使った並列マイグレーションのフロー

worktreeブランチの作成と並列実行
# メインブランチからworktreeブランチを3つ作成
git worktree add ../project-ts-a -b migrate/ts-utils
git worktree add ../project-ts-b -b migrate/ts-components
git worktree add ../project-ts-c -b migrate/ts-services

# 各worktreeで別々のClaude Codeセッションを起動
# ターミナルを3つ開いて並列実行

# ターミナル1: utils/のマイグレーション
cd ../project-ts-a
claude "Migrate all JavaScript files in src/utils/ to TypeScript.
For each file:
1. Rename .js to .ts
2. Add type annotations to all functions and variables
3. Fix any TypeScript errors
4. Run tsc --noEmit to verify
Move to the next file only after each one is clean."

# ターミナル2: components/のマイグレーション
cd ../project-ts-b
claude "Migrate all JavaScript files in src/components/ to TypeScript.
[同様の指示]"

# ターミナル3: services/のマイグレーション
cd ../project-ts-c
claude "Migrate all JavaScript files in src/services/ to TypeScript.
[同様の指示]"
マイグレーション完了後のマージ
# 各ブランチの変換が完了したらメインブランチにマージ
git checkout main
git merge migrate/ts-utils
git merge migrate/ts-components
git merge migrate/ts-services

# worktreeの後片付け
git worktree remove ../project-ts-a
git worktree remove ../project-ts-b
git worktree remove ../project-ts-c
worktreeマイグレーションの注意点
並列マイグレーションでは同じファイルを複数のworktreeで変更しないよう担当ファイルを明確に分けてください。マージ時に大量のコンフリクトが発生します。ファイル一覧を確認してworktreeごとに担当を決めてからClaude Codeに指示するのが安全です。

Checkpointsで安全にロールバックする

Claude Codeはアクションを実行するたびに自動でチェックポイントを作成します。リファクタリング中に「この変更はまずかった」と気づいたとき、チェックポイントからロールバックすることで安全に戻れます。

Checkpointsの操作
# Esc を2回押すか、/rewind コマンドでメニューを開く

# メニューで選択できる操作:
# 1. 会話のみを巻き戻す(コードの変更は保持)
# 2. コードの変更のみを巻き戻す(会話は保持)
# 3. 会話とコード変更の両方を巻き戻す

# コマンド:
# Esc × 2 または /rewind → チェックポイントメニューを表示
シナリオ 推奨するロールバック方法
コンポーネント分割後にテストが大量に壊れた コードとコンテキストを両方巻き戻して別アプローチで再実行
リファクタリングは正しいが説明が間違っていた コードは保持して会話のみ巻き戻す
途中まで良かったが最後の変更だけ戻したい git stashまたはgit checkout HEAD~1 -- ファイル名で個別復元
gitコミットと組み合わせて使う
Checkpointsはセッション内のロールバックです。セッションを跨いで戻ることはできません。大きな変更の前後でgitコミットを作っておくことで、セッションを終了してからでも安全に戻れます。「このフェーズが完了したら一度コミットして」と指示に含めると確実です。

リファクタリングで失敗しやすいパターンと対策

パターン1: 計画なしで一気に実行する

「UserDashboard.tsxをリファクタリングして」と一行で頼むと、Claudeが自分の判断でリファクタリングを実行してしまいます。スコープが曖昧なまま大量のファイルを変更し、動作が壊れるリスクが高まります。

悪い例 良い例
「UserDashboard.tsxをリファクタリングして」 Plan Modeで探索→計画→承認→実装の順で進める
「このコードベースをモダンなTypeScriptにして」 「まず変更対象ファイルをリストアップして。承認後に1ファイルずつ変換する」

パターン2: 検証なしで次の変更に進む

「全部変換してから最後にテスト」という進め方は、何十ファイルもの変更後に大量のテスト失敗が出て修正が困難になります。1ファイル(1機能)変換するたびにテストを実行させる指示が重要です。

ステップごとにテストを確認させる指示
claude "Migrate files in src/utils/ one by one, in alphabetical order.
After each file migration:
1. Run: npx tsc --noEmit
2. Run: npm test -- src/utils/
3. Fix any errors before moving to the next file.
Do not proceed to the next file until all checks pass."

パターン3: コンテキストの汚染に気づかない

リファクタリングが長時間に及ぶと、コンテキストに失敗した試行・古い情報・無関係な変更が積み重なって判断精度が落ちます。同じ修正を2回以上繰り返しているときは/clearしてやり直すのが効果的です。

コンテキストをリフレッシュするタイミング
# 以下のシグナルが出たら /clear を検討する:
# - 同じ修正をしようとして2回以上失敗している
# - Claudeが以前と矛盾する実装方針を提案している
# - 「前回話した〇〇について」という言及が混乱している

/clear

# /clear後は具体的な状況を伝えて再開する
claude "Continuing refactoring of AuthService. So far:
- Completed: createUser(), deleteUser()
- Remaining: updateUser(), getUserById(), listUsers()
- Known issue: updateUser() has a dependency on EmailService that needs mocking

Continue with updateUser() next."

よく使うリファクタリング作業のプロンプトパターン

コンポーネント分割

大きなコンポーネントを分割する
claude "src/components/UserDashboard.tsx is 600 lines long.
Refactor it by extracting:
- StatsGrid component (lines ~50-120)
- ActivityFeed component (lines ~130-280)
- DashboardSidebar component (lines ~300-450)

Rules:
- Keep all data fetching in UserDashboard and pass data as props
- Create TypeScript interfaces for all new props
- Do not change any CSS class names or behavior
- After each extraction, run npm test to verify"

非推奨APIの一括置換

deprecated APIの一括置換
claude "Find all usages of the deprecated fetchUser() API in src/.
List the files first, then replace them one by one with the new getUser() API.
The new signature is: getUser(id: string): Promise<User>
Run tests after each file change."

Classコンポーネント→Hooks移行

ClassコンポーネントをFunctionコンポーネントに変換
claude "Convert src/components/LoginForm.tsx from a class component to
a functional component with hooks.
- Replace this.state with useState
- Replace componentDidMount with useEffect
- Replace componentWillUnmount cleanup with useEffect cleanup
- Replace this.handleX methods with regular functions
Keep the same JSX structure and class names.
Run the existing tests after conversion."

型定義の追加

JavaScriptコードへの型定義追加
claude "Add TypeScript type annotations to src/utils/formatters.js.
For each function:
1. Infer parameter types from how they are called in the codebase
2. Add explicit return types
3. Use strict types (avoid 'any')
4. Create new TypeScript interfaces if needed
Run npx tsc --noEmit after each function."

よくある質問

Qリファクタリング中にテストが大量に壊れました。どうすればいいですか?

Aまず /rewind で変更を巻き戻してください。次に「テストが最初に壊れたのはどの変更か」をClaudeに調べさせます。1ファイルずつ変換してテストを確認するという指示に変え、問題を早期に発見しながら進めてください。テスト自動化の詳細はテスト自動化・TDD完全ガイドを参照してください。

Q大きなリファクタリングをどう小さく分割すればいいですか?

APlan Modeで「このリファクタリングを独立してテスト可能な小さなステップに分割してください。各ステップは1〜2時間で完了でき、それ単体でコミット可能なものにしてください」と依頼すると、Claudeが適切な粒度に分割してくれます。分割後は各ステップを別セッションで実行することで、コンテキスト汚染も防げます。

QStrangler FigパターンとFeature Flagの違いは何ですか?

AStrangler Figは「コード構造を段階的に置き換えていくリファクタリング戦略」、Feature Flagは「実行時に新旧実装を切り替える制御機構」です。両者は組み合わせて使います。Strangler Figで新実装を作り、Feature Flagで本番環境での切り替えを制御することで、ロールバックリスクを最小化できます。

QClaude Codeが計画を立てずにいきなり変更を始めてしまいます

APlan Modeで依頼するか、プロンプトに「make no changes yet」「first create a plan, wait for approval」を明示してください。CLAUDE.mdに「Before refactoring anything: create a plan and wait for approval」と記載しておくと毎回の指示が不要になります。

Qリファクタリング後に本番で問題が起きました。どうすれば防げますか?

A3つの対策を組み合わせてください。①変換前後でテストカバレッジを維持(既存テストが通るだけでなく新しいエッジケースも追加)、②Strangler Figパターン+Feature Flagで段階的なロールアウト(問題が起きたらFlagをオフにすれば即ロールバック)、③重要なリファクタリングはステージング環境で1〜2週間運用してから本番に展開。