LESSON 40分

ストーリー

佐藤CTO
負債の量と利子は分かった。さて、どう返済する?

佐藤CTOが3つの戦略をホワイトボードに書きました。

佐藤CTO
全面書き直しか、段階的リファクタリングか、共存しながら移行するか。答えは99%、段階的リファクタリングだ
あなた
全面書き直しが正解になるケースはないんですか?
佐藤CTO
Joel Spolsky が言った”最悪の戦略的ミスは、コードをスクラッチから書き直すこと”という言葉がある。ただし、例外はある。それも含めて体系的に見ていこう

3つのリファクタリング戦略

戦略適用場面リスク期間
Big Bang Rewrite既存が完全に保守不能、規模が小さい極めて高い長期
Strangler Fig Patternレガシーから段階的に新システムへ移行低〜中中期
Continuous Refactoring日常的な改善の積み重ね低い継続的

Strangler Fig パターン

レガシーシステムを段階的に新システムに置き換えるパターンです。

原理

graph TD
    subgraph P1["Phase 1: Proxy の設置"]
        PR1["Proxy"]
        PR1 --> L1["レガシーシステム(100%)"]
    end

    subgraph P2["Phase 2: 一部機能を新システムへ"]
        PR2["Proxy"]
        PR2 --> L2["レガシー(70%)"]
        PR2 --> N2["新システム(30%)"]
    end

    subgraph P3["Phase 3: 移行完了"]
        PR3["Proxy"]
        PR3 --> N3["新システム(100%)"]
    end

    P1 ~~~ P2 ~~~ P3

    style PR1 fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e40af
    style PR2 fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e40af
    style PR3 fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e40af
    style L1 fill:#fee2e2,stroke:#dc2626,color:#991b1b
    style L2 fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#92400e
    style N2 fill:#d1fae5,stroke:#059669,color:#065f46
    style N3 fill:#d1fae5,stroke:#059669,color:#065f46

実装手順

strangler_fig_steps:
  step1_proxy:
    description: "リバースプロキシを設置し、全トラフィックを通す"
    tools: ["API Gateway", "Nginx", "Envoy"]
    risk: "低(既存に変更なし)"

  step2_identify:
    description: "移行するドメインを選定する"
    criteria:
      - "ビジネス価値が高い"
      - "境界が明確"
      - "依存関係が少ない"
    first_candidate: "最も独立性が高い機能から"

  step3_build:
    description: "新システムで機能を再構築する"
    approach: "レガシーと並行稼働し、結果を比較"

  step4_route:
    description: "トラフィックを段階的に新システムに切り替え"
    pattern: "カナリアリリース(1% → 10% → 50% → 100%)"

  step5_remove:
    description: "レガシーコードを削除"
    timing: "新システムが安定稼働してから"

「Strangler Fig の名前は、熱帯の絞め殺しイチジクから来ている。宿主の木に絡みつき、やがて完全に置き換わる。レガシーを殺すのではなく、新しいシステムが自然に取って代わるんだ」 — 佐藤CTO


ボーイスカウトルール

「来た時よりも美しく」の精神で、触ったコードを少しずつ改善する継続的リファクタリングです。

ルール

graph TD
    RULE["ボーイスカウトルール
コードに触れるたびに
少しだけ改善してコミットする"] RULE --> PRACTICE["具体的な実践"] PRACTICE --> P1["変数名を分かりやすく改名する"] PRACTICE --> P2["マジックナンバーを定数に置き換える"] PRACTICE --> P3["長いメソッドを抽出する"] PRACTICE --> P4["不要なコメントを削除する"] PRACTICE --> P5["テストを1つ追加する"] RULE --> PROHIBIT["禁止事項"] PROHIBIT --> X1["機能追加と大規模リファクタリングを
同じPRに混ぜない"] PROHIBIT --> X2["動作を変えるリファクタリングを
小さなPRに紛れ込ませない"] style RULE fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e40af style PRACTICE fill:#d1fae5,stroke:#059669,color:#065f46 style PROHIBIT fill:#fee2e2,stroke:#dc2626,color:#991b1b style P1 fill:#f3f4f6,stroke:#9ca3af,color:#374151 style P2 fill:#f3f4f6,stroke:#9ca3af,color:#374151 style P3 fill:#f3f4f6,stroke:#9ca3af,color:#374151 style P4 fill:#f3f4f6,stroke:#9ca3af,color:#374151 style P5 fill:#f3f4f6,stroke:#9ca3af,color:#374151 style X1 fill:#f3f4f6,stroke:#9ca3af,color:#374151 style X2 fill:#f3f4f6,stroke:#9ca3af,color:#374151

リファクタリングの粒度

粒度時間アプローチ
微小5-30分変数名改名、メソッド抽出ボーイスカウトルール
1-4時間クラス分割、インターフェース導入ストーリー内タスク
1-3日モジュール再構成、DB移行専用チケット
1-4週間サービス分離、アーキテクチャ変更専用スプリント
特大1ヶ月以上システム移行Strangler Fig

リファクタリング予算

20% ルール

graph TD
    CAP["スプリントキャパシティ: 100%"]
    CAP --> FT["新機能開発: 60%"]
    CAP --> BF["バグ修正: 20%"]
    CAP --> RF["リファクタリング: 20%
← 技術負債の返済枠"] RF --> EX["計算例"] EX --> E1["チーム8名 × 2週間 = 80人日"] EX --> E2["リファクタリング枠: 16人日/スプリント"] EX --> E3["年間投資: 416人日"] style CAP fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e40af style FT fill:#d1fae5,stroke:#059669,color:#065f46 style BF fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#92400e style RF fill:#fee2e2,stroke:#dc2626,color:#991b1b style EX fill:#f3f4f6,stroke:#9ca3af,color:#374151 style E1 fill:#f3f4f6,stroke:#9ca3af,color:#374151 style E2 fill:#f3f4f6,stroke:#9ca3af,color:#374151 style E3 fill:#f3f4f6,stroke:#9ca3af,color:#374151

予算の確保方法

方法メリットデメリット
固定割合(20%ルール)予測可能、持続的柔軟性が低い
リファクタリングスプリント集中して取り組める機能開発が止まる
テックデットスプリント負債を一気に返済燃え尽きリスク
バックログ統合ビジネス価値で優先度判断負債が後回しになりがち

「僕のおすすめは固定割合 + 四半期のテックデットスプリントの組み合わせだ。日常的に20%で利子を払い、四半期に1回、元本を大きく返済する」 — 佐藤CTO


リファクタリングの安全策

大規模なリファクタリングを安全に行うための仕組みです。

safety_nets:
  - name: "テストカバレッジ"
    minimum: "リファクタリング対象の80%以上"
    purpose: "振る舞いが変わっていないことを保証"

  - name: "Feature Flags"
    usage: "新旧ロジックを切り替え可能にする"
    rollback: "問題発生時に即座に旧ロジックに戻す"

  - name: "並行実行(Dark Launch)"
    usage: "新旧のロジックを同時に実行し結果を比較"
    purpose: "本番データでの動作確認"

  - name: "段階的ロールアウト"
    pattern: "1% → 5% → 25% → 50% → 100%"
    purpose: "影響範囲を限定して安全に移行"

  - name: "ロールバック計画"
    requirement: "すべてのリファクタリングにロールバック手順を定義"
    sla: "問題検知から15分以内にロールバック完了"

まとめ

ポイント内容
Strangler Figレガシーを段階的に新システムに置き換える最も安全な戦略
ボーイスカウトルール日常的な小さな改善の積み重ね
リファクタリング予算スプリントの20%を負債返済に確保
安全策テスト、Feature Flags、段階的ロールアウトで安全に実施

チェックリスト

  • 3つのリファクタリング戦略を比較できるようになった
  • Strangler Fig パターンの手順を理解した
  • リファクタリング予算の確保方法を把握した
  • 安全にリファクタリングを行うための仕組みを理解した

次のステップへ

次は「技術負債の経営コミュニケーション」を学びます。定量化した負債とリファクタリング計画を、経営陣にどう伝えるかを見ていきましょう。


推定読了時間: 40分