利益:
- リファクタリング前に現在の動作をキャプチャするテスト セーフティ ネットをセットアップする機能
- AI に小さなワンステップの動作維持変換を依頼し、各ステップを検証する機能
- ビジネスのコンテキスト内で技術的負債を特定し、優先順位を付ける能力
リファクタリングとは、コードの外部の動作を変更せずにコードの内部構造を改善し、コードをより読みやすく、よりシンプルにし、より保守しやすくすることです。一方、技術的負債は、迅速な解決策のために作られた設計上の妥協であり、時間の経過とともに「利息付きで」返済されます。今日手を抜いたすべてが、明日には速度低下やバグとして戻ってきます。人工知能は、反復的で機械的なリファクタリング タスクを高速化する強力なアシスタントです。しかし、リファクタリングには黄金律が 1 つあり、AI だけではそれを保証できません。それは、動作を変えてはいけないということです。
この単元では、AI を使用して安全なリファクタリングを行う方法、つまり、小さくて元に戻せる手順、テストによる保護、コードの臭いの検出、技術的負債の優先順位付けを行う方法を学びます。重要な点は、動作が保存されていることを証明するのは、AI の言葉ではなく、テストに合格したことであるということです。
リファクタリングの黄金律: 動作は一定のまま
リファクタリングが危険なのは、「改善している」と言いながら、無意識のうちに行動を変えてしまうことです。条件を単純化するときにエッジケースを削除する、ループを変換するときに順序を壊す、関数を分割するときに副作用を見逃すなど、すべて「見た目はきれい」ですが壊れたコードが生成されます。
そのため、テストはリファクタリングの前提条件です。変更する前に、既存の動作をキャプチャするテストが必要です。これらのテストは「セーフティ ネット」です。リファクタリング中に誤って何かを壊してしまうと、壊れて警告が表示されます。テストがない場合は、(単元 5 で学習したように) まず既存の動作を修正するテストを作成します。これが AI のスタート地点となります。
注意: テストネットを使用しない AI 支援のリファクタリングは、最も潜伏性のバグの原因の 1 つです。 「私はその行動を保存した」と言うのは簡単です。その証拠は、変更の前後で同じテストに合格したことです。
ステップバイステップ: 安全なリファクタリング フロー
- セーフティネットを設置します。リファクタリングするコードの現在の動作をキャプチャするテストを用意します。そうでない場合は、まずそれらを書き留めてください (そして最後まで確認してください)。
- 匂いに名前を付けます。何を改善していますか?その理由は何ですか? 「この関数は 3 つのことを実行します」、「同じロジックが 4 か所で繰り返されます」、「名前が誤解を招きます」。
- 小さな一歩のステップを求めてください。ファイル全体を書き換えるのではなく、AI に単一の変換 (例: 「この関数を半分に分割する」など) を依頼します。
- テストを実行します。すべてのステップの後。緑の場合は続行し、赤の場合は元に戻します。
- 差分を読み取ります。変更が実際に動作を維持するものであることを 1 行ずつ確認します。 AI が「単なる構造体」であると言う場合、論理のずれがあるかもしれません。
- 小さな部分にまとめます。大規模な 1 回限りのリファクタリング PR はリスクがあり、レビューできません。
ミニケース3個
ケース 1 — 220 行の関数が安全に分割されました。あるチームには 220 行の注文処理機能がありました。現在の動作を捕捉する最初の 14 個のテストが (AI の助けを借りて) 作成され、すべて合格しました。次に、AI によって機能が段階的に 5 つの小さな機能に分割されました。各ステップの後にテストが実行されました。 2 つのテストが 1 つのステップで破られました。AI は、エッジケースでリターンを逃していました。テストではこれをすぐに発見し、修正しました。ネットワークがなければ、エラーは運用環境にまで波及していた可能性があります。
ケース 2 — テストネットなしの災害。別の開発者は、AI によるテストが行われていない日付計算モジュールを「クリーンアップ」しました。コードは改善されたように見えましたが、閏年の計算が間違っていました。このバグは 2 週間後に顧客からの苦情とともに判明しました。この損失は、リファクタリングによって節約された時間をはるかに上回りました。教訓: テストを行わないリファクタリングはギャンブルです。
ケース 3 — 技術的負債の優先順位付け。あるチームは AI に 30 程度の「改善可能」ポイントのバックログを与え、それぞれを「変更頻度 × リスク × 労力」の軸で採点させました。結果のテーブルでは、めったに操作されない醜いモジュールは実際には優先度が低く、頻繁に変更される中程度の複雑さのモジュールは優先度が高くなっています。チームはそのエネルギーを正しい場所に向けました。
4 つのコピー可能なテンプレート
コードの匂いの検出と優先順位付け:
このコード内のリファクタリング候補の「臭い」をリストします: 長い関数、繰り返し (DRYViolation)、誤解を招く名前、深くネストされた条件、隠れた副作用、マジックナンバー。それぞれについて: 場所、問題の理由、提案された小さなステップ、推定リスク (低/中/高)。コードはまだ変更しないでください。計画だけを立ててください。{{code}}
ワンステップの動作維持型変換:
これを行うだけです: {{単一変換、例:この関数を 3 つの小さな名前付き関数に分割します。}}目に見える動作、署名、戻り値を変更します。変更したすべての動作が維持される理由を 1 文で書いてください。{{code}}
リファクタリング前のセーフティ ネット (特性評価テスト):
この関数の現在の動作 (正しいかどうか) をキャプチャするテストを作成します。目標は、リファクタリング中に動作が変化したかどうかを把握することです。典型的な + エッジエントリを含めます。関数の現在の出力に基づいて期待値を記述します。{{function}}
技術的負債記録 (バックログ) の生成:
次の匂いのリストを優先順位付けテーブルに注ぎます: 物質、影響を受ける領域、変更の頻度 (私の知識: {{...}})、リスク、推定労力、推奨される優先順位。インパクトが大きく労力がかからないものを一番上に置きます。 {{匂いリスト}}
弱いプロンプト / 強いプロンプト
弱者: 「このコードをクリーンアップして、改善してください。」
Strong: 「この 90 行の関数を、外部の動作とシグネチャを変更せずに、単一の責任を持つ 3 つの小さな関数に分割します。副作用 (DB 書き込み) を現在の順序に保ちます。テストはありますが、動作は同じままでなければなりません。差分を示し、それぞれの分割が動作を保持する理由を 1 文で説明してください。[コード]」
強力なバージョン。単一の特定の変換が必要であり、動作と署名の制約を明示的に課し、正当化を要求します。 「もっと良くしてほしい」などの漠然とした要求は、制御不能で危険な変更につながります。
リファクタリングの種類
AIの信頼性
前提条件
名前を変更する
高い
範囲は正しいですか?
機能分割
中~高
テストネットは必須
共有の繰り返し
中程度
動作の違いが隠れている可能性がある
アルゴリズム・構造変更
低い
広範なテスト + 人間による検証
アーキテクチャの再配置
低い
人間主導、AI サポート
技術的負債をリセットするのではなく、管理する
技術的負債は悪いことばかりではありません。場合によっては、(納期に間に合うように)意識的に借りることが正しい決断となることもあります。目標は借金をなくすことではなく、借金を可視化して管理しやすくすることです。 AI は負債を迅速に検出して優先順位を付けることができますが、「どの負債を支払うべきで、どの負債を放棄すべきか」を決定するには、ビジネス コンテキストが必要です。つまり、このモジュールはどのくらいの頻度で変更され、何人に影響を及ぼし、リスクは何でしょうか?この決定は、コード ベースと製品を理解しているチームによって行われます。 AIは選択肢を明確にするだけです。
ヒント: リファクタリング PR は、動作変更を伴う PR とは別にしてください。 「この PR は単なるリファクタリングで、動作は同じです」と言えると調査が容易になり、問題が発生した場合にすぐに原因を絞り込むことができます。
よくある間違い
- テストネットを使用しないリファクタリング。動作が保存されていることを証明するものは何も残りません。
- 「ファイル全体をクリアする」という意味です。制御されていない大規模な変更はエラーを隠し、調査することができません。
- Diff を読まずに受け入れます。 AIは「単なる構造」と言うときに、いくつかの論理を滑らせた可能性があります。
- リファクタリングと動作の変更を混同している。同じ PR 内で両方を実行すると、根本原因の追跡が不可能になります。
- あらゆる臭いを解決しようとします。ほとんど変更されない醜いコードは優先度が低いことがよくあります。頻繁に変化する場所にエネルギーを割り当てます。
要約すると
リファクタリングの唯一のルールは、動作が一定のままであることです。これを証明するのがテストです。 AI は、コードの匂いの検出、ワンステップの変換、技術的負債の優先順位付けにおいて強力です。ただし、セーフティ ネットを設定し、テストを実行し、各ステップの後に差分を読み取る必要があります。小さくて元に戻せるステップを踏みましょう。リファクタリングと動作変更を区別する。そして、ビジネスの背景を知っているチームにどの負債を支払うかを決定させます。
アプリケーションタスク
コードベースから、長かったり複雑に見える関数を選択してください。まず、「セーフティ ネット」テンプレートを使用して現在の動作をキャプチャするテストを印刷し、すべてがパスするかどうかを確認します。次に、「ワンステップ、動作保持変換」パターンを使用して単一の方法 (半分に分割するなど) で関数をリファクタリングし、テストを再度実行します。テストが失敗した場合は、その理由を調べてください。まったく壊れない場合は、diff を 1 行ずつ読んで、動作が実際に保持されていることを確認します。
チェックリスト
- [ ] リファクタリングによって動作が変わるべきではなく、それを証明するテストがあることはわかっています。
- [ ] リファクタリング前に現在の動作を捕捉するセーフティ ネットを設定しています。
- [ ] 私が望んでいるのは、AI による一度限りの大きな変革ではなく、小規模で 1 ステップの変革です。
- [ ] 各ステップの後にテストを実行し、差分を読み取ります。
- [ ] 私は動作変更 PR とは別に PR をリファクタリングし続けています。
- [ ] 私は、盲目的にゼロにしようとするのではなく、ビジネスの背景に合わせて技術的負債を優先します。