概要
リファクタリング(コードの動作を変えずに構造を改善)は、AIが効果的に支援できるタスクです。ただし、適切な依頼方法とレビューが重要です。
リファクタリングの前に、必ずテストを用意する。
リファクタリング依頼の基本
1. 改善目的を明確にする
「いい感じに直して」ではなく、具体的な改善目的を伝えます。
- 可読性向上:長い関数を分割、命名改善
- パフォーマンス改善:計算量削減、キャッシュ導入
- 保守性向上:責務分離、依存関係整理
- テスト容易性向上:依存性注入、モジュール分離
2. 悪い例と良い例
❌ 悪い例
このコードをリファクタリングして
def process_order(order):
# 長いコード...
✓ 良い例
【対象コード】
def process_order(order):
# 長いコード...
【リファクタリングの目的】
この関数が200行を超えており、以下の問題があります:
1. 複数の責務(検証、計算、DB更新、通知)が混在
2. テストが書きにくい
3. 変更時の影響範囲が大きい
【要望】
- 責務ごとに関数を分割
- 各関数は単一責任の原則に従う
- 元の動作は維持(テストがパスすること)
【既存のテスト】
def test_process_order_success():
...
def test_process_order_invalid_item():
...
テスト駆動リファクタリング
手順
- テストを確認:既存のテストがあることを確認(なければ先に作成)
- テストを実行:リファクタリング前にすべてパスすることを確認
- AIにリファクタリングを依頼:目的とテストを提示
- テストを再実行:リファクタリング後もすべてパスすることを確認
- コードをレビュー:改善目的が達成されているか確認
⚠️ テストなしのリファクタリングは危険
テストなしでリファクタリングすると、動作が変わったことに気づけません。
テストがない場合は、先にテストを作成してからリファクタリングしましょう。
段階的リファクタリング
大きなリファクタリングは、小さなステップに分割します。
【ステップ1】
まず、検証ロジックを別関数に抽出してください。
- validate_order_items()
- validate_payment_info()
【ステップ2】
(レビュー後)
次に、割引計算を別関数に抽出してください。
- calculate_discounts()
【ステップ3】
(レビュー後)
最後に、通知処理を別クラスに分離してください。
- OrderNotificationService
よくあるリファクタリングパターン
関数の分割
【依頼例】
以下の関数を責務ごとに分割してください。
現在の関数は150行あり、以下の処理を行っています:
1. 入力検証(30行)
2. データ変換(40行)
3. DB操作(50行)
4. レスポンス生成(30行)
各責務を独立した関数に分割し、
メイン関数からそれらを呼び出す形にしてください。
命名改善
【依頼例】
以下のコードの変数名・関数名を改善してください。
【現在の規約】
- 関数名: snake_case、動詞から始める
- 変数名: snake_case、意味が明確に
【コード】
def proc(d):
x = d['val']
y = calc(x)
return {'r': y}
重複コードの統合
【依頼例】
以下の2つの関数に重複したロジックがあります。
共通部分を別関数に抽出してDRY原則に従ってください。
【関数1】
def create_user(...):
# 検証ロジック(重複)
# ユーザー作成
【関数2】
def update_user(...):
# 検証ロジック(重複)
# ユーザー更新
参考文献
- Martin Fowler "Refactoring" (2nd Edition)
- Michael Feathers "Working Effectively with Legacy Code"
次へ
→ テストコード生成
→ 段階的依頼技法