第5章:「スパゲッティコード」を解剖する 🍝🔪
〜どこを直すとどこが壊れるか分からない恐怖を、ちゃんと見える化する〜 😱🧩
この章でできるようになること 🎯✨
- 「なんか怖い…」を言語化できるようになる 🗣️
- 変更すると壊れそうな場所を、先にあぶり出す手順がわかる 🔍
- いきなり大改造せずに、安全に触るコツを持ち帰れる 🛡️
まず、あるあるストーリー 🎬😇
「送料の計算だけ直せばいいよね〜」って思って、ちょっとだけ触ったら… なぜかポイント付与が壊れた、さらにメール通知が二重送信、最後に在庫がマイナス… ……なにこれ!!!😭😭😭
これが、スパゲッティの恐怖です🍝💥
スパゲッティコードって何?🍝

ひとことで言うと…
“どこを触ると何が起きるか、コードから読み取れない状態” 😵💫
パスタみたいに、
- ぐちゃぐちゃ絡まってて
- 1本引っぱったら全部ついてきて
- 切ったらどこが切れたかわからない
そんな状態です🍝🌀
スパゲッティ化してるサイン一覧 🚨👀
当てはまったら要注意!
- 1つのメソッドが長すぎる(スクロール地獄)📜😇
ifがネストしまくり(迷路)🌀bool isXxxフラグで分岐が増殖(スイッチだらけ)🎚️- いろんな所で同じ変数をいじってる(誰が変えたの?)🫠
- DB/ファイル/メール送信が“ついでに”混ざってる(副作用パーティ)🎉😱
- 変更するとき「祈る」🙏(これ最重要サイン)
「どこを直すとどこが壊れるか分からない」の正体 🧠💡
ほぼこれです👇
① 依存関係がベタベタ 🤝🫠
AがBを呼び、BがCを呼び、CがAを呼び…みたいな循環も起きがち。
② 1つの場所が、いろんな役をやってる 🎭
計算も、保存も、通知も、ログも、全部1メソッドでやってると 「どれを変えたらどれが影響受けるの?」が読めなくなる😵💫
③ 副作用が隠れてる 💣
「計算してるだけに見えて、実は保存してる」みたいなやつ。 これが一番ヤバいです😇
解剖の基本手順:7ステップ 🧩🔍
「直す」前に「分解して観察」するよ〜!🧑🔬✨
1) 変更したいことを1文にする 📝
例:
- 「送料を、地域ごとに変えたい」🚚
- 「ポイント付与の条件を変えたい」🎁
ここがブレると、全部ブレます😵💫
2) 入口(スタート地点)を決める 🚪
Windows + Visual Studioなら超ラク👇
- 変更対象っぽいメソッドを右クリック → “呼び出し階層”(Call Hierarchy)🔍
- Controller/Handler/Clickイベントなど「外から入る場所」を探す👀
3) “読んでるもの/書いてるもの”を列挙する 📋
そのメソッドが触ってるものを、雑でいいから書き出す✍️
- 読む:引数、プロパティ、DB、設定値
- 書く:DB更新、メール送信、ログ、状態変更
書いてるものが多いほど危険度UP💣
4) 副作用にマーカーを付ける 🧷
見つけたら、コメントでもメモでもOK👇
- DB保存(
SaveChangesなど)🗃️ - 外部API呼び出し 🌐
- メール/通知 ✉️
- ファイルIO 📁
「ここ触ると世界が動く」ポイントです😱
5) “関係者”をリストアップする 👥
関わってるクラス・サービス・テーブル・設定値など。 Visual Studioなら
- “すべての参照を検索”(Find All References)🔎 が超強い!
6) 影響範囲を予想する(壊れ方を先読み)🔮
「送料を変える」なら
- 合計金額
- クーポン
- ポイント
- メール文面
- 注文確定の条件 …みたいに波及する可能性がある🌊
この“可能性リスト”があるだけで、恐怖が減ります😌✨
7) 安全柵を置く(触る前にガード!)🛡️
いきなり綺麗にしようとしない!まずはこれ👇
- ログを追加して挙動を見る 🧾
- 既存挙動を固定する「ざっくりテスト」を置く ✅
- 変更は小さく、小さく、小さく 🐣
ミニ解剖:スパゲッティ例 🍝(C#)
「送料を直したいだけ」なのに、いろいろ混ざってる例です😇
public class OrderService
{
private readonly AppDbContext _db;
private readonly EmailSender _email;
public OrderService(AppDbContext db, EmailSender email)
{
_db = db;
_email = email;
}
public decimal Checkout(int userId, int orderId, string region, bool useCoupon)
{
var order = _db.Orders.Find(orderId);
if (order == null) throw new Exception("Order not found");
if (order.UserId != userId) throw new Exception("Not yours");
decimal total = 0;
foreach (var item in _db.OrderItems.Where(x => x.OrderId == orderId))
{
total += item.Price * item.Quantity;
}
// coupon
if (useCoupon)
{
var coupon = _db.Coupons.FirstOrDefault(x => x.UserId == userId && x.IsUsed == false);
if (coupon != null)
{
total -= 500;
coupon.IsUsed = true; // ← DB状態変更(副作用)
}
}
// shipping
if (region == "Tokyo") total += 600;
else if (region == "Osaka") total += 700;
else total += 900;
// points
if (total >= 3000) order.PointsGiven = 30;
else order.PointsGiven = 10;
order.Total = total;
order.Status = "Paid";
_db.SaveChanges(); // ← DB保存(副作用)
_email.Send(order.Email, "Thanks!", $"Total={total}"); // ← 通知(副作用)
return total;
}
}
どこが「怖い」の?😱🔍
- 合計計算(純粋な計算)🧮
- クーポン消費(DB状態変更)🗃️
- 送料ルール(条件分岐)🚚
- ポイント付与(別ルール)🎁
- 注文ステータス更新(状態遷移)🔄
- DB保存(副作用)💣
- メール送信(副作用)💥
1つのメソッドに“世界を動かす処理”が詰まりすぎです🍱💦
解剖メモの付け方(超実用)📝✨
このコードを解剖するなら、メモはこんな感じでOK👇
- 変更したい:送料(shipping)🚚
- 影響しそう:total → points → email文面 → order status 🔗
- 副作用:coupon.IsUsed更新、SaveChanges、Email送信 💣
- 危険:送料変更したらポイント境界(3000円)またぐ可能性あり ⚠️
これを書けた時点で、もう勝ちです😌🏆
“安全に触る”ための最小リファクタ3手 🍀🔧
いきなり理想形にしない!まずは怖さを減らす!
① 計算だけを外に出す(副作用ゼロにする)🧼
private static decimal CalcSubtotal(IEnumerable<OrderItem> items)
=> items.Sum(x => x.Price * x.Quantity);
private static decimal CalcShipping(string region)
=> region switch
{
"Tokyo" => 600,
"Osaka" => 700,
_ => 900
};
これだけで「送料の変更」が触りやすくなります😌✨
② 副作用ゾーンを固める(最後にまとめる)🧱
DB保存やメール送信は、できれば最後の方に寄せる📦
③ “結果”を一度変数に集める 🧺
「途中で order を書き換えまくる」を減らすと事故率が下がります🚑
Visual Studioでの“迷子防止”セット 🧭💻
- 呼び出し階層(Call Hierarchy):入口探しに最強 🔍
- すべての参照を検索:関係者リスト作りに最強 👥
- Find in Files(Ctrl+Shift+F):文字列
"Paid"とか追うと発見ある😳 - ブレークポイント & ウォッチ:変数がどこで変わるか見る👀
AIと一緒に解剖する🧠🤝✨(おすすめプロンプト)
AIは「見落とし発見」が得意です🔍 その代わり、丸投げはNG!“解剖メモ”を一緒に作る感じがいいよ😊
① 副作用を洗い出す
このC#メソッドの「副作用(外部状態の変更)」を全部列挙して。
DB更新・外部通信・状態変更・ログ出力など、種類ごとに分類して。
② 変更の波及を予想する
「送料計算のルールを変える」とき、壊れやすいポイントを列挙して。
特に合計金額に依存している処理(ポイント、割引、メール、状態遷移)を疑って。
③ 最小の安全柵(テスト案)を出してもらう
現状の挙動を壊さないために、まず追加すべき「最小のテストケース」を提案して。
送料の境界値、ポイント境界値、クーポン有無を中心に。
ミニワーク(10〜20分)✍️⏰🎀
あなたの(または過去の)コードで、これやってみて!
-
「変更したいこと」を1文で書く 📝
-
その周辺メソッドの
- 読んでるもの
- 書いてるもの を箇条書きにする 📋
-
副作用(DB/通知/外部)に💣マークを付ける
-
「壊れそうリスト」を3つ書く 😱➡️😌
できたら、そのメモをそのままAIに渡すとめちゃ進みます🤝✨
まとめ 🍝✨
スパゲッティコードは「悪」っていうより、“見えない”のが怖いんだよね😇 だからこの章のゴールはこれ👇
- 直す前に、まず 解剖して見える化する 🔍
- 副作用と依存関係を把握して、安全に触る🛡️
- 小さく切り分けて、恐怖を減らす ✂️😌
次の章以降で、さらに「迷わないための型」を手に入れていこうね〜!💪🌸