ストーリー
佐藤CTOが3つの戦略をホワイトボードに書きました。
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分