プログラミングを長年やっていると、「こういう時はこうすればうまくいく」というやり方が自然と身についてくる。でも、それに正式な名前があることを知らずに使っていることがよくある。
最近、自分が普段使っている設計手法に、ちゃんとした名前が付いていることを知った。他のエンジニアと会話するときに「あのやり方、あれですよ」と言うより「Strangler Fig Pattern で」と言えた方が圧倒的に話が早い。
この記事では、僕が知らずに使っていたパターンたちをまとめておく。特に Feature Flag や「式変形みたいなやり方」に名称があったのは驚きだった。
古い建物を建て替えるとき、どうする?一度全部壊してから新しく建てる方法もあるけど、住みながら・使いながら少しずつ改修していく方法もある。
プログラミングの世界でも同じ。今動いているシステムを止めずに、新しい仕組みに置き換えたい。そんな時に使える「定番の手法」がいくつかある。
こういった手法に名前が付いていると:
僕自身、「式を変形するように少しずつコードを書き換える」やり方を長年使っていたけど、それが Strangler Fig Pattern という名前だと最近知った。名前を知ってから、関連する情報がどんどん見つかるようになった。
熱帯雨林に生える「絞め殺しイチジク」という植物から名付けられた。この植物は:
1. 他の木に種が落ちる 2. その木を支えにして成長する 3. やがて元の木を覆い尽くす 4. 最終的に元の木は枯れて、イチジクだけが残る
ちょっと怖い名前だけど、システム移行のプロセスにぴったりの比喩だ。
古いシステムを一度に置き換えるのではなく、新しいシステムで徐々に機能を置き換えていく手法。
旧システム (レガシー) ↓ [一部を新システムで置き換え] ↓ [さらに置き換え範囲を拡大] ↓ [最終的に旧システムは不要に] ↓ 新システムのみ
例えば、会員管理システムを刷新するとき:
1. まず「新規会員登録」機能だけ新システムで作る 2. 次に「ログイン機能」を新システムに移行 3. 徐々に「プロフィール編集」「退会処理」なども移行 4. 最後に旧システムを停止
各ステップでテストして、問題があれば戻せる。一気に全部作り直すより安全だ。
Martin Fowler の「Building Microservices」でも、モノリシックなシステムからマイクロサービスへの移行戦略として紹介されている。
コードレベルで「抽象レイヤー」を挟んで、実装を段階的に切り替える手法。
// 抽象レイヤー(インターフェース)
interface PaymentService {
processPayment(amount)
}
// 旧実装
class OldPaymentService implements PaymentService { ... }
// 新実装
class NewPaymentService implements PaymentService { ... }
// 切り替え
if (useNewImplementation) {
service = new NewPaymentService()
} else {
service = new OldPaymentService()
}
両方を組み合わせることもできる。Strangler Fig の各ステップで Branch by Abstraction を使う、といった具合だ。
「設定で機能のON/OFFを切り替える」という単純な仕組み。でも、これにちゃんと名前があったのを最近知った。
if (featureFlags.isEnabled("NEW_CHECKOUT_FLOW")) {
// 新しいチェックアウトフロー
return newCheckout(cart)
} else {
// 従来のチェックアウトフロー
return oldCheckout(cart)
}
1. カナリアリリース:一部のユーザーだけに新機能を公開 2. A/Bテスト:複数バージョンを比較 3. 段階的ロールアウト:5%→20%→50%→100%と徐々に展開 4. 緊急停止:問題が起きたら即座にOFF
Feature Flag の方が柔軟だけど、管理が複雑になる。古いフラグの削除を忘れると技術的負債になる。
フラグの寿命を意識する:
期限を決めて、不要になったら必ず削除する。
本番環境を2つ用意(Blue と Green)して、瞬時に切り替える手法。
[ロードバランサー]
↓
Blue環境(現行) ← ユーザーのトラフィックはこちら
Green環境(待機) ← 新バージョンをデプロイ
↓
[動作確認OK]
↓
[ロードバランサーの向き先を切り替え]
↓
Blue環境(待機)
Green環境(現行) ← ユーザーのトラフィックがこちらに
| パターン名 | スコープ | 切り替えタイミング | 主な用途 | リスク |
| Strangler Fig | システム全体 | 数週間〜数ヶ月 | レガシー移行 | 低(段階的) |
| Branch by Abstraction | コードレベル | コンパイル時 | 大規模リファクタ | 低〜中 |
| Feature Flag | 機能単位 | 実行時 | 段階的リリース | 中(管理複雑) |
| Blue-Green | デプロイメント | デプロイ時 | 本番切り替え | 低(即切り戻し可) |
実際のプロジェクトでは、これらを組み合わせることが多い:
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 で本番環境を無停止切り替え
数学で式を変形するとき、一気に答えを出すんじゃなくて、少しずつ変形していく:
(x + 2)(x + 3) = x² + 3x + 2x + 6 = x² + 5x + 6
各ステップで式は正しくて、最終的に簡単な形になる。
Strangler Fig も同じ:
[旧システム] = [旧システムの一部 + 新機能A] = [旧システムのさらに一部 + 新機能A + 新機能B] = [新システム]
各ステップでシステムは動作していて、最終的に新システムになる。この「動いたまま変形する」という考え方が、式変形に似ていると僕は感じた。
Feature Flag に正式な名前があったこと。「設定で切り替える」なんて当たり前すぎて、パターンとして認識していなかった。でも、これも立派な設計戦略なんだと分かった。
パターンを知ると、次に学ぶべきことも見えてくる。これからも「あのやり方」に名前を見つけていきたい。
Fumiya、この記事読んでくれた?
プログラミングって、最初は「コードを書く」ことばかり考えるけど、実は「どう変更するか」の方が大事だったりする。システムは生き物みたいなもので、ずっと変化し続ける。
今回紹介したパターンは、全部「変化に強いシステムを作る」ための知恵。数学の公式みたいに、先人が発見してくれた「うまくいく方法」なんだ。
名前を知っていると、世界中のエンジニアと同じ言葉で話せる。それって結構すごいことだと思わない?