* 目次 [#p3384d90]
#contents

* 僕が無意識に使っていた設計パターンたちに、ちゃんと名前があった話 [#o147f1b4]

** はじめに:「あのやり方」に名前があった [#cc89719b]

プログラミングを長年やっていると、「こういう時はこうすればうまくいく」というやり方が自然と身についてくる。でも、それに正式な名前があることを知らずに使っていることがよくある。

最近、自分が普段使っている設計手法に、ちゃんとした名前が付いていることを知った。他のエンジニアと会話するときに「あのやり方、あれですよ」と言うより「Strangler Fig Pattern で」と言えた方が圧倒的に話が早い。

この記事では、僕が知らずに使っていたパターンたちをまとめておく。特に Feature Flag や「式変形みたいなやり方」に名称があったのは驚きだった。

** なぜパターンに名前が必要なのか [#r3afc8c5]

*** 身近な例で考えてみる [#m6fe153d]

古い建物を建て替えるとき、どうする?一度全部壊してから新しく建てる方法もあるけど、住みながら・使いながら少しずつ改修していく方法もある。

プログラミングの世界でも同じ。今動いているシステムを止めずに、新しい仕組みに置き換えたい。そんな時に使える「定番の手法」がいくつかある。

*** 共通言語としての価値 [#kfbbc5a4]

こういった手法に名前が付いていると:

- チーム内で「Strangler Fig で行きましょう」と一言で済む
- 調べればすぐに詳しい情報が見つかる
- 他社の事例も「同じパターン名」で検索できる
- 設計レビューで議論しやすくなる

僕自身、「式を変形するように少しずつコードを書き換える」やり方を長年使っていたけど、それが Strangler Fig Pattern という名前だと最近知った。名前を知ってから、関連する情報がどんどん見つかるようになった。

** パターン1: Strangler Fig Pattern(絞め殺しイチジクパターン) [#k774bdbc]

*** 名前の由来 [#v6ef79f1]

熱帯雨林に生える「絞め殺しイチジク」という植物から名付けられた。この植物は:

1. 他の木に種が落ちる
2. その木を支えにして成長する
3. やがて元の木を覆い尽くす
4. 最終的に元の木は枯れて、イチジクだけが残る

ちょっと怖い名前だけど、システム移行のプロセスにぴったりの比喩だ。

*** どんなパターンか [#t2285d96]

古いシステムを一度に置き換えるのではなく、新しいシステムで徐々に機能を置き換えていく手法。

 旧システム (レガシー)
    ↓
 [一部を新システムで置き換え]
    ↓
 [さらに置き換え範囲を拡大]
    ↓
 [最終的に旧システムは不要に]
    ↓
 新システムのみ

*** 具体例 [#ka57a532]

例えば、会員管理システムを刷新するとき:

1. まず「新規会員登録」機能だけ新システムで作る
2. 次に「ログイン機能」を新システムに移行
3. 徐々に「プロフィール編集」「退会処理」なども移行
4. 最後に旧システムを停止

各ステップでテストして、問題があれば戻せる。一気に全部作り直すより安全だ。

*** いつ使う? [#ze885f20]

- 大規模なレガシーシステムの刷新
- ビジネスを止められないサービスの移行
- リスクを最小化したい案件

Martin Fowler の「Building Microservices」でも、モノリシックなシステムからマイクロサービスへの移行戦略として紹介されている。

** パターン2: Branch by Abstraction [#l7b2b3e3]

*** どんなパターンか [#rac8babd]

コードレベルで「抽象レイヤー」を挟んで、実装を段階的に切り替える手法。

 // 抽象レイヤー(インターフェース)
 interface PaymentService {
   processPayment(amount)
 }
 
 // 旧実装
 class OldPaymentService implements PaymentService { ... }
 
 // 新実装
 class NewPaymentService implements PaymentService { ... }
 
 // 切り替え
 if (useNewImplementation) {
   service = new NewPaymentService()
 } else {
   service = new OldPaymentService()
 }

*** Strangler Fig との違い [#weea3ed3]

- Strangler Fig: システム全体の移行戦略(マクロな視点)
- Branch by Abstraction: コードレベルの切り替え手法(ミクロな視点)

両方を組み合わせることもできる。Strangler Fig の各ステップで Branch by Abstraction を使う、といった具合だ。

*** メリット [#fa275e90]

- mainブランチを壊さずに大規模リファクタリングができる
- 常にデプロイ可能な状態を保てる
- 問題があれば即座に旧実装に戻せる

** パターン3: Feature Flag / Feature Toggle 戦略 [#m1a1150f]

*** 僕が名前を知らなかったパターン [#t6f60761]

「設定で機能のON/OFFを切り替える」という単純な仕組み。でも、これにちゃんと名前があったのを最近知った。

 if (featureFlags.isEnabled("NEW_CHECKOUT_FLOW")) {
   // 新しいチェックアウトフロー
   return newCheckout(cart)
 } else {
   // 従来のチェックアウトフロー
   return oldCheckout(cart)
 }

*** どんな時に使う? [#fd41137e]

1. カナリアリリース:一部のユーザーだけに新機能を公開
2. A/Bテスト:複数バージョンを比較
3. 段階的ロールアウト:5%→20%→50%→100%と徐々に展開
4. 緊急停止:問題が起きたら即座にOFF

*** Branch by Abstraction との違い [#g616cac9]

- Branch by Abstraction: コンパイル時に切り替え先を決める
- Feature Flag: 実行時(ランタイム)に切り替える

Feature Flag の方が柔軟だけど、管理が複雑になる。古いフラグの削除を忘れると技術的負債になる。

*** 実装のコツ [#obf044a8]

フラグの寿命を意識する:

- 短命フラグ:リリース後1-2週間で削除(リリース用)
- 中期フラグ:数ヶ月単位(A/Bテスト用)
- 長期フラグ:永続的に残す(プレミアム機能のON/OFFなど)

期限を決めて、不要になったら必ず削除する。

** パターン4: Blue-Green Deployment [#re4c2c11]

*** どんなパターンか [#z36b4f5a]

本番環境を2つ用意(Blue と Green)して、瞬時に切り替える手法。

 [ロードバランサー]
        ↓
  Blue環境(現行) ← ユーザーのトラフィックはこちら
  Green環境(待機) ← 新バージョンをデプロイ
        ↓
 [動作確認OK]
        ↓
 [ロードバランサーの向き先を切り替え]
        ↓
  Blue環境(待機)
  Green環境(現行) ← ユーザーのトラフィックがこちらに

*** メリット [#d32a4218]

- ダウンタイムゼロ
- 問題があれば即座に切り戻し(ロードバランサーを戻すだけ)
- 新環境で事前に十分なテストができる

*** デメリット [#i2f15203]

- 環境を2倍用意するコスト
- データベースの移行が複雑になる場合がある
- 両環境で状態を同期する必要がある

*** いつ使う? [#p312bf83]

- 高可用性が求められるサービス
- ダウンタイムが許されないシステム
- 新バージョンへの切り替えリスクを最小化したい時

** パターンの使い分け [#yd247aa6]

*** 比較表 [#w0457160]

|パターン名|スコープ|切り替えタイミング|主な用途|リスク|
|Strangler Fig|システム全体|数週間〜数ヶ月|レガシー移行|低(段階的)|
|Branch by Abstraction|コードレベル|コンパイル時|大規模リファクタ|低〜中|
|Feature Flag|機能単位|実行時|段階的リリース|中(管理複雑)|
|Blue-Green|デプロイメント|デプロイ時|本番切り替え|低(即切り戻し可)|

*** 組み合わせて使う例 [#de0368dc]

実際のプロジェクトでは、これらを組み合わせることが多い:

1. Strangler Fig の戦略で全体を段階的に移行
2. 各機能は Branch by Abstraction で実装を切り替え
3. 本番リリースは Feature Flag で段階的に展開
4. 最終的な切り替えは Blue-Green Deployment で

例:
 [全体戦略] Strangler Fig で旧システムから段階移行
    ↓
 [実装] Branch by Abstraction でコード切り替え
    ↓
 [公開制御] Feature Flag で 5% → 50% → 100%
    ↓
 [デプロイ] Blue-Green で本番環境を無停止切り替え

** 式変形のようなやり方 [#g60ac301]

*** Strangler Fig は「式変形」に似ている [#b36de193]

数学で式を変形するとき、一気に答えを出すんじゃなくて、少しずつ変形していく:

 (x + 2)(x + 3)
 = x² + 3x + 2x + 6
 = x² + 5x + 6

各ステップで式は正しくて、最終的に簡単な形になる。

Strangler Fig も同じ:

 [旧システム]
 = [旧システムの一部 + 新機能A]
 = [旧システムのさらに一部 + 新機能A + 新機能B]
 = [新システム]

各ステップでシステムは動作していて、最終的に新システムになる。この「動いたまま変形する」という考え方が、式変形に似ていると僕は感じた。

** まとめ:名前を知ることで得られたもの [#b8c4933c]

*** 学んだこと [#xd306755]

- 自分が使っていた手法に、ちゃんと名前があった
- 名前を知ると、情報がたくさん見つかる
- チームで話すときの共通語になる
- それぞれのパターンには使いどころがある

*** 特に驚いたこと [#j31af43b]

Feature Flag に正式な名前があったこと。「設定で切り替える」なんて当たり前すぎて、パターンとして認識していなかった。でも、これも立派な設計戦略なんだと分かった。

*** 次に学びたいこと [#q80e88e0]

- Canary Release(カナリアリリース)の詳細
- Database Migration のベストプラクティス
- Chaos Engineering(意図的に障害を起こしてテスト)

パターンを知ると、次に学ぶべきことも見えてくる。これからも「あのやり方」に名前を見つけていきたい。

** 参考資料 [#ue5d57a3]

- Martin Fowler: "Strangler Fig Application"
- "Building Microservices" - Sam Newman
- "Continuous Delivery" - Jez Humble, David Farley
- LaunchDarkly Blog: Feature Flag Best Practices

** 息子へ [#z610c1d9]
** まとめ [#z610c1d9]

Fumiya、この記事読んでくれた?

プログラミングって、最初は「コードを書く」ことばかり考えるけど、実は「どう変更するか」の方が大事だったりする。システムは生き物みたいなもので、ずっと変化し続ける。

今回紹介したパターンは、全部「変化に強いシステムを作る」ための知恵。数学の公式みたいに、先人が発見してくれた「うまくいく方法」なんだ。

名前を知っていると、世界中のエンジニアと同じ言葉で話せる。それって結構すごいことだと思わない?
トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS