リファクタリングとは
リファクタリング(Refactoring)とは、プログラムの「外部から見た動作や機能」は一切変えずに、内部のソースコードの構造を整理して、より読みやすく、メンテナンスしやすい綺麗な状態に書き直す作業のことです。
システム開発を続けていると、場当たり的な修正が重なり、プログラムが複雑で読みづらい状態(いわゆるスパゲティコード)になりがちです。そのまま放置すると、新しい機能を追加しにくくなったり、バグが混入しやすくなったりします。リファクタリングを行うことで、重複しているコードを共通化したり、分かりづらい変数名をシンプルな名前に変更したりして、コードの品質を保ちます。なお、機能自体は変えないため、実行前にテストが全て通ることを確認し、リファクタリング後も同じテストが通る(デグレードがない)ことを確認しながら進めます。
具体例
以下のような、重複した計算処理をすっきり整理するリファクタリングの例です。
【修正前(重複が多い状態)】
price1_with_tax = price1 * 1.10
price2_with_tax = price2 * 1.10
【修正後(関数にまとめて共通化)】
def add_tax(price):
return price * 1.10
price1_with_tax = add_tax(price1)
price2_with_tax = add_tax(price2)
もう少し詳しく
リファクタリング(Refactoring)とは、プログラムの「外部から見た動作や機能」は一切変更せず、ソースコードの「内部の構造」だけを整理して、美しく分かりやすいコードへと改善する作業です。
プログラムは、機能追加やバグ修正を繰り返すうちに、コードが複雑化し、冗長で読みにくい状態(技術的負債)に陥りやすくなります。これを放置すると、将来の仕様変更時にバグが発生しやすくなり、開発速度が低下します。リファクタリングでは、重複するコードを共通関数にまとめたり、長すぎるメソッドを適切に分割したり、変数や関数に分かりやすい名前を付け直したりします。
これを安全に行うための絶対条件は、「テストコード(単体テスト)が存在すること」です。リファクタリング前とリファクタリング後でテストを実行し、機能が変わっていないことを保証しながら、少しずつコードを書き換えていきます。
試験でのポイント
試験では、リファクタリングの定義について問われます。「プログラムの外部仕様(動作や機能)を変えずに、内部構造を整理して保守性を高めること」という定義を選択させる問題が基本です。
「機能追加」や「バグ修正」はリファクタリングの定義には含まれない(むしろそれらを同時に行ってはならない)という点が、間違いやすい引っかけポイントとして出題されます。また、リファクタリングを安全に進めるために、テストを自動実行する「単体テスト」の存在必要不可欠であるという技術的アプローチについても問われます。
関連する用語
関連する用語には、リファクタリング前後で動作が変わっていないかを検証する「回帰テスト(リグレッションテスト)」、安全なコード変更を保証する「テスト駆動開発(TDD: Test-Driven Development)」、およびコードの読みにくさや乱雑さを表す「技術的負債(テクニカルデット)」があります。