外科医のメスでコードを救え ― 海外エンジニアが編み出した “戦略的切り離し術” のススメ**

  1. 沼にはまったレガシーコードと、僕が握った“メス”
  2. ■ レガシーの怖さは「汚い」ではなく「触ると壊れる」こと
  3. ■ “全部書き直したい病”が最大の失敗
  4. ■ 外科医の“メスの入れ方”をコードに応用するという発想に出会う
    1. それを支える3つのメソッド
  5. ■ なぜ海外では“メス”が求められるのか?
    1. ① コードベースが巨大
    2. ② 多国籍で認識共有が難しい
    3. ③ 実装スピードが重視される
  6. ■ 僕が学んだ“外科医の心得”
  7. ■ 自分の中で革命が起きた瞬間
  8. ■ 起まとめ
  9. 絡み合うコードを少しずつ“締めていく”技術
  10. ■ 古いコードを「理解しよう」とするのをやめた瞬間からすべてが動き出す
  11. ■ ステップ① “現場の触れるべき場所”を見つける
  12. ■ ステップ② 新しい“枝”を作り、古い“幹”に巻きつける
    1. 例:WPF の画面更新機能を修正するとき
  13. ■ ステップ③ 少しずつ責務を“奪っていく”
  14. ■ ステップ④ 古い部分を“締め付けて”いく
  15. ■ Strangler Fig の本質は「成果を分割する」ことにある
  16. ■ Strangler Fig を成功させるための3つのコツ
    1. ① 「戻せるようにしておく」
    2. ② 「一気に大きなリファクタリングをしない」
    3. ③ 「チームに小さな勝利を積み重ねる」
  17. ■ 承のまとめ
  18. 触った場所だけを救うという戦略的ワガママ
  19. ■ Feature First とは「必要な場所だけ救う」こと
  20. ■ 「善意のリファクタリング」が最大の事故を生む
  21. ■ Feature First の核心は“境界線引き”
    1. ① 呼び出し元を2段階だけ追う
    2. ② UI → VM → Model の流れを紙に書き出す
    3. ③ 「今回触るのはどこ?」を赤ペンで囲む
  22. ■ Feature First を使うと、リファクタリングは「差し替え」になる
    1. Before
    2. Feature First のやり方
  23. ■ 「直したいけど直せない」葛藤との向き合い方
  24. ■ 海外で評価されるのは「勇気ある割り切り」
    1. ① 余計なバグを生まない
    2. ② プロジェクト全体の進捗が読みやすい
    3. ③ レガシー脱出の速度が結果的に上がる
  25. ■ Feature First 実践チェックリスト(僕が毎回使っている)
  26. ■ 「承 → 転」で流れがどう変わったか
  27. テストが作る「撤退できる勇気」と「攻められる自信」
  28. ■ Test-Driven Extraction の目的は「保険をかける」こと
  29. ■ ステップ① 「観測テスト」で現状の動きを固定する
    1. 観測テストの目的
    2. → 大きな改善をしても、壊した時に必ず気付ける。
  30. ■ ステップ② 「抽出先(新クラス)」に観測テストをそのまま移植する
  31. ■ ステップ③ 古いコードのロジックを“静脈注射のように抜き取る”
    1. 抽出のコツ
  32. ■ ステップ④ 全ての責務が新クラスへ移ったら、古いクラスを削除する
  33. ■ Test-Driven Extraction が海外で絶対的に評価される理由
    1. ① バグを早期に検知できる
    2. ② ロールバックが簡単
    3. ③ チーム全体の開発速度が上がる
  34. ■ 結のまとめ:3つの武器が揃った瞬間、レガシーは敵ではなくなる

沼にはまったレガシーコードと、僕が握った“メス”

(サブタイトル:「カオスの渦に飲み込まれた日」


海外で開発していると、文化や働き方の違いももちろん大変なんだけど、一番きつかったのはレガシーコードとの戦いでした。
「海外のエンジニアは合理的で洗練されたアーキテクチャを使っている」——そんな幻想は、現場に入った初週で粉々に砕け散ります。

実際は、
“なぜ動いているかわからないけど動いている恐怖のブラックボックス”
が、あなたを待っています。

特に僕の場合は、某国の大規模プロジェクトで WPF アプリケーションの保守・追加開発を担当したときのこと。

  • DataContext がどこで設定されてるのかわからない
  • VM が 3 階層くらい勝手にネスト
  • Trigger が 9 個重なって UI が怪しく点滅
  • 1 メソッド 800 行

初見で理解するのを諦め、正直 胃がキリキリしました。


■ レガシーの怖さは「汚い」ではなく「触ると壊れる」こと

レガシーコードって「見た目が汚い」ってことが問題じゃありません。
本質的には、

  • 依存が絡まりあいすぎて修正すると他が壊れる
  • テストがなく、変更が恐怖
  • どこから手をつけていいか分からない

この「絡まりあい」が本当に危険なんです。

僕たちはそれをStrangler Fig(絞殺榕)パターンと呼びます。
太い木に巻き付いて少しずつ締め付けながら生長する木の名前から来ていて、

「古いコードを徐々に“絞め殺す”ように、新しいコードへ置き換える」

という発想。

言葉としては知っていました。でも、現場で向き合うとその難しさがよくわかるんです。


■ “全部書き直したい病”が最大の失敗

レガシーを前にすると、開発者としてつい言いたくなるんですよ。

「全部作り直したほうが早くない?」

これ、僕も言いました。チームでもよく聞く言葉です。

でも、海外の Senior Engineer の一言で目が覚めました。

“If you rewrite everything, you will rebuild all the bugs as well.”
(全部書き直したら、全部のバグを作り直すことにもなる。)

確かに。
ゼロから書くということは、既存の「暗黙の仕様」や「歴史的経緯」を全部失う

しかも、海外のプロジェクトは巨大で複雑。
仕様が多国籍チームの中で曖昧さを孕んでいて、関係部署も多く、テストも簡単じゃない。

だから “全部書き直す” は現実的ではないんです。

その瞬間から、僕のアプローチはガラッと変わりました。


■ 外科医の“メスの入れ方”をコードに応用するという発想に出会う

ここで登場したのが、今回のテーマである
Strategic Disentanglement(戦略的切り離し)
いわば “外科医のメス” のように最小限だけ切り出すアプローチです。

それを支える3つのメソッド

  1. Strangler Fig Pattern(少しずつ置き換える)
  2. Feature First(変更の影響がある箇所だけ触る)
  3. Test-Driven Extraction(テストで安全を確保しながら分離する)

この3つを実践的に組み合わせると、
「壊さずに前に進める」ようになります。


■ なぜ海外では“メス”が求められるのか?

僕が働いてきた海外の現場では、特にこの「外科医アプローチ」が強く求められる理由が3つあります。

① コードベースが巨大

10年以上運用されてきたプロダクトが多く、全体を書き換えるのは不可能。

② 多国籍で認識共有が難しい

「これって仕様?」
「いや、知らない…」
みたいな会話が日常茶飯事。
大規模リライトなんて到底できない。

③ 実装スピードが重視される

特に欧米は「早く動くものを出す文化」。
大規模書き換えはROIが合わない。


■ 僕が学んだ“外科医の心得”

ある Senior のアドバイスが、今も忘れられません。

“We don’t fix everything.
We fix what we touch.”
(全部は直さなくていい。触ったところだけ直せばいい。)

これが Feature First の精神です。

さらに続けてこう言いました。

“If you cut something out, always add a safety net.”
(何かを切り離すなら、必ず安全網を用意しろ。)

ここでいう安全網=テスト。
これが Test-Driven Extraction の核心。


■ 自分の中で革命が起きた瞬間

この発想に出会ってから、レガシーコードを見る恐怖が減りました。
なぜなら、

“全部理解する必要はない”
“触った部分だけ、安全に切り離せばいい”

という明確な戦略ができたから。

結果的に、新機能もバグ修正もスムーズになり、
海外チームでも「お前のリファクタリングは安全で速い」と評価されるようになりました。


■ 起まとめ

今回の「起」では、

  • レガシーとの初対面の恐怖
  • 全部書き換えるという幻想の否定
  • 外科医のメスという発想との出会い
  • なぜ海外では“部分的切り離し”が重要か
  • 3つのメソッドが必要になる背景

ここまでを物語ベースでお伝えしました。

次の「承」では、
Strangler Fig Pattern をどう実践し、どのように既存コードを“締め付けて”いくか
をさらに深掘りしていきます。

絡み合うコードを少しずつ“締めていく”技術

(サブタイトル:「Strangler Fig パターンを現場で使い倒す」


海外で働いていて気づいたのは、大規模プロジェクトほど“いきなり完璧”を誰も期待していないということだった。
むしろ、期待されているのは、小さく前進し続けるための仕組みだ。

そう、まさに Strangler Fig(絞殺榕)パターンの精神そのもの。

木の幹に巻きつきながら、時間をかけて古い構造を置き換えていくように、
“触った部分から新しい世界に移行していく”
という考え方。

ここでは、僕が実際の海外現場でどう使っているかを、エンジニア目線で深掘りしていく。


■ 古いコードを「理解しよう」とするのをやめた瞬間からすべてが動き出す

まず大前提として、Strangler Fig パターンには明確な鉄則がある。

「古いコードを全部理解しない。理解するのは触る部分だけ。」

昔の僕は「コードは全部知るべきだ」と本気で思っていた。
でも、それは少人数で作った個人プロジェクトの感覚だったと気付かされた。

海外の大規模プロダクトでは、
「誰も全体を完全に理解していない」
というのが現実だ。

むしろ、

  • わからない部分は見ない
  • 危ない部分は触らない
  • 壊すリスクがある場所は避ける

そんな “サバイバル的な賢さ” が求められる。

Strangler Fig は、まさにそのための戦術だ。


■ ステップ① “現場の触れるべき場所”を見つける

まず何より大事なのが “触れるところだけ見つける” こと。

僕がやっているのは、この3つ。

  1. 今回の新機能・改修が依存する箇所を最小限に特定する
  2. その部分だけを理解する(周辺は理解しない)
  3. そのコードの“境界線”を引く

この3つをやるだけで、世界が一気にスッキリする。

実際に境界線を引いてみるとわかるけど、
「この部分だけを新世界に移せばいい」
という感覚が生まれる。

巨大なコードの海で、救命ボートを見つけたような気分になる。


■ ステップ② 新しい“枝”を作り、古い“幹”に巻きつける

Strangler Fig における次のフェーズは、

「新しいコードを、古いコードの横にそっと置く」

これが海外現場で本当に重宝される。

例:WPF の画面更新機能を修正するとき

  • 既存コードは View + ViewModel + 何かよくわからない Helper + 古代遺跡のような Converter
  • どこで値が変更されているのか不明
  • イベントが 3 重でネストしている

そんな地獄が普通にある。

そこでやるのは、
“新しい ViewModel(もしくは新しいクラス)を横に作る”
という発想だ。

ポイントは、
置き換えではなく、まず並べる。

いきなり置き換えると壊す。
だから、まずは並走させる。


■ ステップ③ 少しずつ責務を“奪っていく”

新しい枝を作った後は、その枝に少しずつ“役割”を移していく。

  • 1つのメソッドを新VMへ移動
  • 1つのバリデーションを新ロジックへ移動
  • 1つのUI更新だけを新クラスへ移動

たったこれだけでも、現場は「慎重で丁寧」と評価してくれる。

海外では特に、
「壊さないこと」が絶対的価値
として見られている。

日本では「技術力がある=複雑な実装ができる」みたいに見られることもあるけど、海外は逆だ。

“The best engineer is the one who changes the least.”
(最も少ない変更でゴールへ近づける人が最高のエンジニアだ)

この価値観と Strangler Fig は、実はめちゃくちゃ相性がいい。


■ ステップ④ 古い部分を“締め付けて”いく

新しいコードが徐々に育ち、古いコードの負担が減っていくと、
“絞めつけ”のフェーズに入れる。

これはつまり、

  • 古い関数を呼ばなくなる
  • 古いクラスの責務がゼロになる
  • 参照がなくなる

そして、役目を終えた古い部分は削除できる。

ここで最高に気持ちいい瞬間が訪れる。

巨大で理解不能だったコードが、跡形もなく削除される。

正直、こればかりは本当に快感だ。


■ Strangler Fig の本質は「成果を分割する」ことにある

Strangler Fig で最も大事なのは、

「成果物を分割し、部分的にリリースできる状態をつくること」

海外だと、
「まずは1画面だけ新しいパターンに移行しよう」
とか
「今回触るのはこの関数の20行だけ」
みたいに、成果を細かく区切っていく。

この積み重ねで、気がついたら

  • 古いロジックは半分以下になり
  • 新しい設計がプロジェクトの主流になり
  • バグ修正も新基盤で高速になり
  • チーム全体の開発スピードが上がる

こんな状態になっている。

まさに、絞殺榕がゆっくりと古い木を覆い尽くすように。


■ Strangler Fig を成功させるための3つのコツ

僕が海外で学んだ中で、特に重要だと感じたのはこの3つ。

① 「戻せるようにしておく」

つまり、
“古いコードを消さずに新しいコードを並べる”
のが最初。

これは安全性の確保。

② 「一気に大きなリファクタリングをしない」

5%の改善を20回やったほうが、
1回の100%改善より安全で速い。

③ 「チームに小さな勝利を積み重ねる」

小さな成功は、

  • コードレビューの信頼
  • チームの安心感
  • 自分の評価
    すべてにつながる。

Strangler Fig が優れているのは、
“小さな成功を量産できる点”
なのだ。


■ 承のまとめ

この「承」では、Strangler Fig パターンを

  • どこから始めるのか
  • なぜ全体を理解する必要がないのか
  • 新しいコードをどう並走させるのか
  • 少しずつ責務を奪っていく戦略
  • 海外で評価される理由

といった実践的な視点で深掘りした。

次の「転」では、
いよいよ Feature First(触った部分だけ切り出していく技術) について、
より“戦闘的なテクニック”を解説していく。

あなたのレガシーとの戦いは、ここからさらに楽になるはず。

触った場所だけを救うという戦略的ワガママ

(サブタイトル:「Feature First ― 最小の努力で最大の効果を生む技術」)


レガシーコードの“全体最適”を夢見ていた頃の僕にとって、
Feature First の考え方は衝撃だった。

「修正が必要なのはこの機能だけだけど、
せっかくだし周辺も綺麗にしたいよね?」

以前の僕なら、確実にそう言っていた。

でも海外で経験を重ねて痛感したのは、
“触ってもいない場所まで、善意で直すのは危険行為”
だということだ。

ここからは、僕が海外の現場で徹底的に叩き込まれた
Feature First の戦略的な本質を解き明かしていく。


■ Feature First とは「必要な場所だけ救う」こと

Feature First のキーワードはたった一つ。

「触った機能に関係する範囲だけ切り出し、だけ改善し、だけ劇的に変える」

これを守ると何が起きるか?

  • リスクが最小になる
  • 改修スピードが上がる
  • テスト範囲が絞れる
  • チームからの信頼が上がる
  • レガシーの脱出速度が accelerates(加速する)

特に海外では、この考え方が強烈に支持されている。

「今回関係ない場所は絶対に触るな」という文化がある。


■ 「善意のリファクタリング」が最大の事故を生む

僕が海外で失敗したエピソードを一つ。

ある日、WPF の古い画面に新機能を追加するタスクが来た。
コードは 10 年選手で、DataContext の行方は謎、イベントの嵐。
正直、この世の地獄だった。

そこで僕は、「ついでに周辺も綺麗にしておくか…」と考え、
ViewModel のメソッドを Win32API のような巨大化したヘルパーからいくつか切り出した。

結果どうなったか?

海外 QA(品質保証)チームから14件のバグ報告が来た。

「え、触ってない場所なのに?」
「なんで?」
となるのだが、理由はシンプル。

レガシーは“触ってない場所”が一番危険。
何かがどこかでつながっている。

それ以来、
僕は「周辺もついでに直す」ことを完全にやめた。


■ Feature First の核心は“境界線引き”

最初にやることは、
「今回の機能が依存しているコードの“境界”を明確にすること」
これが Feature First のスタートライン。

境界線はどうやって見つけるか?

僕が使っている3つの手順がある。

① 呼び出し元を2段階だけ追う

3段階以上追うと地獄。
2段階でやめるのが鉄則。

② UI → VM → Model の流れを紙に書き出す

意外に紙に書くと俯瞰できる。

③ 「今回触るのはどこ?」を赤ペンで囲む

赤く囲んだ場所以外は絶対触らない。

この“赤ペンルール”、海外では普通にやっている。


■ Feature First を使うと、リファクタリングは「差し替え」になる

境界線を引いたら、次にやるのは
“必要な部分をだけ” 新しいクラス・VM に差し替えること。

たとえば…

Before

public void UpdateCustomerView()
{
var data = DataHelper.GetSomethingVeryOld();
// 謎の計算処理
// 謎のフラグ操作
// 謎の UI 更新
}

Feature First のやり方

  1. UpdateCustomerView の 内部だけ 切り出す
  2. 新しい CustomerUpdateService を作る
  3. UpdateCustomerView から呼ぶだけにする

たったこれだけ。

これでも十分な改善なのだ。


■ 「直したいけど直せない」葛藤との向き合い方

Feature First の最大の敵は、
エンジニアの“きれいにしたい欲” だ。

ソフトウェアエンジニアなら誰でも持っている。

けれど、海外の Senior が言ったこの一言が刺さった。

“Contain your desire.”
(その欲を、閉じこめろ。)

なぜなら、
「ついで」で直した部分が壊れた時、
それは“本来必要な修正”ではないからだ。

プロジェクト的には損失でしかない。

そこを割り切るのが、
Feature First の美学。


■ 海外で評価されるのは「勇気ある割り切り」

僕が海外で学んだ最大のポイントはこれ。

“触らない勇気” が最も評価される。

理由は3つ。

① 余計なバグを生まない

触らなければ壊さない。

② プロジェクト全体の進捗が読みやすい

範囲が最小なので予測しやすい。

③ レガシー脱出の速度が結果的に上がる

小さく確実に改善すると、
最後は雪崩のように改善が進み始める。

Feature First は、
「レガシーを救う唯一の現実的戦略だ」と痛感している。


■ Feature First 実践チェックリスト(僕が毎回使っている)

  1. 今回の機能の範囲は明確か?
  2. 依存関係は2段階以上追っていないか?
  3. 新規コードを“横に並べる”設計になっているか?
  4. 周辺を直したくなる欲を抑えたか?
  5. 今回の変更はロールバック可能か?

これを守るだけで、
改善速度が 2 倍以上になった。


■ 「承 → 転」で流れがどう変わったか

  • 承では「徐々に置き換える」技術(Strangler)
  • 転では「触った部分だけ救う」技術(Feature First)

この2つが組み合わさると、
大規模レガシーも現実的に突破できる。

そして次の「結」で、いよいよ最後の要素…

Test-Driven Extraction
(テスト駆動で安全に切り離す技術)

を解き明かします。

これが揃うと、
“レガシーとの戦いに勝てるエンジニア” に変わる。

テストが作る「撤退できる勇気」と「攻められる自信」

(サブタイトル:「Test-Driven Extraction ― レガシーを剥がす最後の一手」)


Strangler Fig(徐々に置き換える)
Feature First(触った機能だけ救う)

ここまでの2つは、“レガシーと戦わない戦略” といってもいい。

そして最後に必要になるのは、
「安全に切り離すための技術」
つまり Test-Driven Extraction だ。

僕が海外現場で最も強く叩き込まれたのは、

テストは「成功を保証するもの」ではなく
「失敗した時に戻れるようにしてくれるもの」だ。

この価値観だった。

テストを使って古いコードを少しずつ剥がし取り、新しいロジックへ置き換えていく。
その中で “攻める勇気” と “撤退する安全性” の両方を確保できる。

ここでは、実際に僕がやっている Test-Driven Extraction のリアルな手順と、
それが海外の開発でなぜ絶大な信頼を生むのかを深堀りしていく。


■ Test-Driven Extraction の目的は「保険をかける」こと

まず最初に理解しておきたいのは、
Test-Driven Extraction は
「きれいに書き直すための技術」ではない
ということだ。

目的はただ一つ。

“壊した時に気付けるようにする”

WPF のような UI 絡みのコードは特に危険で、
いつ UI スレッドが詰むか、いつイベントが二重に発火するか、
それほど古いコードは予測できない。

だからこそ、
古いコードに対して“観測テスト”を置くことで、
「今の振る舞いを記録しておく」
ことが最初のステップになる。


■ ステップ① 「観測テスト」で現状の動きを固定する

観測テスト(Characterization Test)は、
海外現場で頻繁に使われる概念。

日本ではあまり知られていないけれど、
レガシー攻略では間違いなく最強の手だ。

観測テストの目的

  • 現在の動作が正しいかどうかは判断しない
  • ただ「今こう動いている」という事実を記録する
  • 今後の改修で変化があればすぐ検知できる

つまり、

「このコードは腹立つけど、今はこう動くんだよね?」
という証拠を残す作業

WPF の画面更新でも同じで、

  • どのプロパティが更新されるか
  • どんな値が返ってくるか
  • どんな例外が飛ぶか
  • どの条件で分岐するか

これをすべて “そのまま” テストに残す。

すると何が起きるか?

→ 大きな改善をしても、壊した時に必ず気付ける。

これがあるだけで、心が圧倒的に軽くなる。


■ ステップ② 「抽出先(新クラス)」に観測テストをそのまま移植する

現状を観測できたら、いよいよ新しいクラスへの抽出だ。

ここで重要なのは、
「テスト → 抽出」ではなく「テストを持って移動する」
という発想。

  1. 旧コードに観測テストを書く
  2. 新しいクラスを作る
  3. 観測テストの一部を新クラスに向けて書き換える
  4. 古いコードはテスト対象から外していく

この“テストの引っ越し”が実に強力で、
新しいクラスが完全に旧コードと同じ振る舞いになった瞬間がわかる。

つまり、

テストが「設計図」になる

これは海外の Senior たちがよく言っていたこと。

「仕様書はどこに?」とか、
「ドキュメントは?」とか、
そんな質問をすると、必ずこう返ってくる。

“The test is the documentation.”
(テストこそがドキュメントだ)

レガシー攻略では、この考え方が本当に生きる。


■ ステップ③ 古いコードのロジックを“静脈注射のように抜き取る”

観測テストと新クラスができたら、
ロジックを少しずつ抽出していく。

このとき、Strangler Fig と Feature First の要素が合体する。

抽出のコツ

  1. ロジックを小片に分解する
  2. 小片を新クラスに移動
  3. テストを動かして差異がないことを確認
  4. 問題なければ古いコード側の該当部分を消す

このステップを繰り返すだけで、
巨大な古代遺跡のようなコードの“血管”を一本一本抜き取ることができる。

まさに手術のような作業。

だからこそ、
僕はこの方法を
「サージカル・リファクタリング(外科手術的リファクタリング)」
と呼んでいる。


■ ステップ④ 全ての責務が新クラスへ移ったら、古いクラスを削除する

海外現場で最も気持ちいい瞬間。

古い巨大クラスを丸ごと削除できた瞬間。

観測テストがあるから、
削除しても挙動が変わらないことが保証されている。

  • この安心感
  • この安全性
  • この達成感

全部、テストがくれるものだ。


■ Test-Driven Extraction が海外で絶対的に評価される理由

理由は3つある。

① バグを早期に検知できる

壊す前に止められる。

② ロールバックが簡単

「前のバージョンに戻す」判断がすぐできる。

③ チーム全体の開発速度が上がる

安全性が高いと、大胆な改善ができる。

これらはすべて、海外エンジニアリングマネージャーが
最も重視する要素だ。


■ 結のまとめ:3つの武器が揃った瞬間、レガシーは敵ではなくなる

ここまで3つの戦略を深掘りしてきた。

  1. Strangler Fig
    → レガシーを徐々に絞めていく戦略
  2. Feature First
    → 触った部分だけを救う戦略
  3. Test-Driven Extraction
    → 動作を保証しながら安全に切り離す戦略

これらは独立しているように見えて、
実はすべて連動している。

「触ったところだけ抽出する」

「テストで挙動を固定する」

「新世界は少しずつ広がり、旧世界 は徐々に消えていく」

その結果、
10 年積み上がったレガシーコードも、
無理なく、無茶なく、安全に置き換わっていく。

そして何より大きいのは、
この3つを使えるエンジニアは海外で圧倒的に評価されるということ。

理由はシンプル。

“レガシーと戦えるエンジニアは、どんな現場でも価値がある。”

これほど強い武器はない。

コメント

タイトルとURLをコピーしました