01リファクタリングとは何か ── Fowler の定義
まず言葉を正確にしておきます。この語を広めたのは、マーチン・ファウラー(Martin Fowler)の著書『Refactoring』(1999 年、第 2 版 2018 年)です。定義は明快です ── 外から見たソフトウェアの振る舞いを変えずに、内部の構造を改善すること。肝は「振る舞いを変えない」という条件です。バグを直すのでも、機能を足すのでもありません。同じことをする、けれど中身をきれいにする。この一点が、リファクタリングを他の作業から分けます。
なぜこんな地味な作業に一冊が費やされたのか。コードは「一度書いて終わり」ではないからです。医薬品の解析プログラムも、帳票を作る仕組みも、規制やデータ様式が変わるたびに手が入ります。そのとき、絡まった構造は変更を難しくし、直すたびに新しいバグを生みます。リファクタリングは、将来の変更を安く・安全にするための、いわば土地の整地です。
ファウラーは、機能追加とリファクタリングを別々の帽子にたとえました。いま自分はどちらの帽子をかぶっているのか、はっきり意識せよ、と。振る舞いを変える作業(機能追加・バグ修正)と、変えない作業(リファクタリング)を混ぜると、何が原因で壊れたのか分からなくなります。この「帽子を混ぜない」という規律が、AI 支援でも土台になります。
02AI の提案を、どう使うか
生成 AI は、リファクタリングの提案が得意です。長い関数を分ける、重複を一つにまとめる、変数名を分かりやすくする ── こうした定型の改善を、数秒で示します。人間なら見落とす重複を機械的に拾うのも上手です。ここは素直に力を借りてよい場面です。
ただし、使い方には順序があります。AI に「このコードをきれいにして」と丸投げし、返ってきたものをそのまま採用する ── これが最も危険なやり方です。AI は、構造を整えるついでに振る舞いをこっそり変えることがあるからです。条件の境界を少しずらす、例外の扱いを変える、丸め方を変える。見た目はきれいになったのに、出力が微妙に違う。製薬の解析コードでこれが起きれば、結果の数値そのものが変わってしまいます。
提案は「候補」として受ける
AI の出力は、完成品ではなく下書きです。何を変えたのかを一つずつ読み、意図をつかんでから採否を決める。読まずに採用しない。
「何を変えたか」を言わせる
AI に、変更の要点を言葉で説明させる。「振る舞いは保たれているか」をはっきり問う。説明できない変更は疑う。
一度に一種類だけ
名前の整理と構造の分割を同時に頼まない。一種類の改善に絞れば、レビューも検証も追いやすい。
要するに、AI は提案者であって、決定者ではありません。決めるのは人です。この主従が崩れると、速さと引き換えに、見えない振る舞いの変化を抱え込むことになります。
03振る舞いは、本当に保たれたか ── 検証
「振る舞いを変えない」という約束は、気合や目視では守れません。守れているかを確かめる仕組みが要ります。その中心が、自動テスト(=プログラムが正しく動くかを、別のプログラムで自動確認する仕組み)です。
ケント・ベック(Kent Beck)は『Test-Driven Development』(2002 年)で、テストを安全網(safety net、=落ちても受け止めてくれる網)と呼びました。リファクタリングでは、この網が命綱になります。手を入れる前にテストが全部通ることを確かめ、手を入れた後にもう一度、全部通ることを確かめる。前後で結果が同じなら、振る舞いは保たれたと言えます。テストがなければ、リファクタリングは「たぶん大丈夫」の賭けになります。
| 段階 | やること | 確かめる問い |
|---|---|---|
| 着手前 | 既存テストを全て実行し、緑(全通過)を確認 | いま、振る舞いはテストで固定されているか |
| 作業中 | 小さく直すたびに、こまめにテストを回す | いまの一手で、何かが赤(失敗)に変わっていないか |
| 完了後 | 再度、全テストが緑であることを確認 | 着手前と、外から見た結果は同じか |
テストが薄い、あるいは無いコードをリファクタリングするなら、順序が逆になります。まずいまの振る舞いを写し取るテストを書く。マイケル・フェザーズ(Michael Feathers)は『Working Effectively with Legacy Code』(2004 年)で、これを characterization test(=現状の振る舞いをそのまま記録するテスト)と呼びました。正しいかどうかは一旦問わず、「いまこう動く」を固定してから、構造に手を入れる。AI にテストの叩き台を書かせるのは有効ですが、そのテストが本当に境界を突いているかは、人が点検します。
04小さな差分の原則
リファクタリングで最も効く規律は、一度に小さく直すことです。大きく書き換えて最後にまとめてテスト、ではありません。小さく直して確かめ、また小さく直して確かめる。この刻みを細かくするほど、壊れた瞬間を特定しやすくなります。
理由は、失敗の切り分けにあります。100 行を一気に変えてテストが赤くなったら、原因はその 100 行のどこか。探すのに時間がかかります。5 行だけ変えて赤くなったなら、原因はその 5 行の中。すぐ戻せて、すぐ直せる。差分が小さいほど、間違いは安く済みます。
AI 支援では、この原則がとくに大切です。AI は求めれば、大きな書き換えを一息で出してきます。見た目の完成度が高く、つい丸ごと採用したくなる。けれど大きな差分は、レビューでも検証でも「全体をなんとなく眺めて OK」に流れがちです。細かな振る舞いの変化は、その大きさに紛れて見えなくなります。AI に大きく出させても、人は小さく取り込む ── 一塊を分割し、意味のわかる単位ごとに、テストを挟みながら入れていく。この翻訳作業こそ、人が担う中心です。
05レビューの役割 ── 書いた人と、見る人を分ける
AI がコードを書き、同じ AI がそれを「問題ありません」と評価する ── これは検証になりません。書き手と評価者が同じなら、書き手の盲点は、そのまま評価者の盲点だからです。人間の世界で、資材を作った本人が自分で審査を通さないのと同じ理屈です。作る役と、見る役は、分けます。
リファクタリングのレビューで、見る人が問うべきことは、機能追加のレビューとは少し違います。「新しく何ができるようになったか」ではなく、「本当に、前と同じことをするか」が中心の問いです。具体的には、次を確かめます。
- 振る舞いの保存 ── 入力と出力の対応が、変更前と一致しているか。境界・例外・エラー時の挙動まで含めて同じか。
- 差分の大きさ ── 一つの変更が、追える大きさに収まっているか。混ぜすぎていないか。
- テストの裏づけ ── その変更を守るテストが存在し、緑であるか。テストが薄い箇所を黙って通していないか。
- 意図の説明 ── なぜこの構造にしたのかが、コミットやコメントから読み取れるか。AI の提案を、理由も分からず取り込んでいないか。
AI をレビューの補助に使うのは有効です。見落としの候補を挙げさせ、人が最終判断する。ただし順序を守ります ── 生成のパスと、検証のパスを分ける。同じ文脈で書かせて自己承認させない。これが、盲点の連鎖を断つ柵になります。
06危険なパターン ── AI 支援で起きやすい失敗
ここまでの裏返しとして、避けるべき型をまとめます。どれも「速いから」という理由で起きます。
丸ごと採用
AI の出力を読まずにそのまま取り込む。何が変わったか把握しないまま進むため、振る舞いの変化に気づけない。
帽子の混在
リファクタリングのついでに機能も直す。壊れたとき、原因が構造変更か機能変更か切り分けられなくなる。
テストなしで着手
安全網を張らずに構造を触る。前後の同一性を確かめる手段がなく、「たぶん大丈夫」の賭けになる。
巨大な一括変更
大きな差分を一度に入れる。レビューも検証も全体を眺めるだけになり、細かな逸脱が紛れる。
四つに共通するのは、速さを優先して、確かめる手順を飛ばしていることです。AI はこの誘惑を強めます。もっともらしく完成した大きな塊を、一瞬で出してくるからです。だからこそ、速さを受け止める側に、崩さない柵が要ります。
07運用 ── 記録が問われる現場で
製薬の解析コードや帳票生成のように、結果が規制や記録に関わるソフトウェアでは、リファクタリングの運用に一段の慎重さが要ります。厚生労働省の「医薬品・医薬部外品製造販売業者等におけるコンピュータ化システム適正管理ガイドライン」(2010 年)は、システムの変更を管理し、記録に残すことを求めています。振る舞いを変えない改善であっても、変更した事実と、それが妥当だと確かめた記録は残す ── これが運用の土台です。
具体的には、次の三つを回します。第一に、変更前後で結果が一致することの証拠を残す。テストの通過記録や、同一データでの出力比較がこれにあたります。第二に、誰が・何を・なぜ変えたかを追えるようにする。バージョン管理(=変更の履歴を全て残す仕組み)には、AI の提案をそのまま入れず、人が意図を書き添えて記録する。第三に、作る人とは別の人が確認する。第 5 節のレビューを、正式な工程として組み込みます。
AI 支援は、この運用と相性が良い面もあります。変更の要約を下書きさせ、テストの叩き台を作らせ、レビューの観点を洗い出させる ── 記録づくりの手間を軽くできます。ただし、生成させた記録を人が読まずに提出するのは、第 6 節の「丸ごと採用」と同じ失敗です。記録は、後で誰かが読んで意味が通ってこそ価値があります。速く作れることと、正しく残せることは、別の目標として両立させます。
08本サイトの他の章との接続
今回は、次の章と読み合わせると理解が厚くなります。
- AI Programming 第 6 回 ── ドキュメント生成 ── リファクタリングで整えた構造を、文書としてどう残すか。コードから文書を自動生成する限界を扱う。
- 資材審査シリーズ ── 作る役と見る役を分ける発想は、コードのレビューでも資材の審査でも同じ。人と人の確認の実務。
- AI Marketing 第 5 回 ── AI 生成コンテンツ戦略 ── 生成の速さの内側に検証を組み込む設計。コードでもコンテンツでも、構造は共通する。
リファクタリングの芯は、ファウラーの定義そのままです ── 外から見た振る舞いを変えずに、内部を整える。AI はこの作業を速くしますが、速さは「振る舞いを保つ」という約束を破る危うさと表裏です。だから守るべき柵ははっきりしています。テストで前後の同一性を確かめる。差分を小さく刻む。作る役と見る役を分ける。そして、変更した事実と妥当性を記録に残す。
AI は提案者であって、決定者ではありません。大きくきれいな塊を一息で出してきても、人は小さく取り込み、一つずつ確かめる。この主従と順序を崩さないかぎり、AI 支援のリファクタリングは、将来の変更を安く・安全にする土地の整地になります。次回は、整えた構造を文書として残す ── コードから文書を自動生成する試みと、その限界に進みます。
- リファクタリングは、外から見た振る舞いを変えずに内部を整える作業(Fowler の定義)。機能追加やバグ修正とは「帽子」を分け、混ぜない。AI は提案者であって決定者ではない ── 何を変えたかを読み、理解してから採否を決める。
- 「振る舞いを保った」は気合ではなくテストで確かめる。着手前に全テストが緑であることを確認し、完了後にもう一度確認する。テストが薄いコードは、まず現状の振る舞いを写し取るテスト(characterization test)を書いてから着手する。
- 差分は小さく刻み、作る役と見る役を分け、変更の事実と妥当性を記録に残す。速く作れることと正しく残せることは別の目標。同じ AI に書かせて自己承認させず、生成のパスと検証のパスを分ける。
- Martin Fowler. Refactoring: Improving the Design of Existing Code. Addison-Wesley, 1999(第 2 版 2018). (「リファクタリング」の定義と手順の原典)
- Kent Beck. Test-Driven Development: By Example. Addison-Wesley, 2002. (テストを安全網とする考え方の出典)
- Michael Feathers. Working Effectively with Legacy Code. Prentice Hall, 2004. (characterization test など、テストの薄いコードへの着手法)
- Robert C. Martin. Clean Code: A Handbook of Agile Software Craftsmanship. Prentice Hall, 2008. (命名・関数分割など、読みやすさの原則)
- 厚生労働省. 医薬品・医薬部外品製造販売業者等におけるコンピュータ化システム適正管理ガイドライン. 2010. (記録が問われるソフトウェアの変更管理の一次資料)