メインコンテンツまでスキップ

第1章 はじめまして不変条件🌱✨

今日のゴール🎯

  • 不変条件(Invariants)=「絶対守る約束」って、自分の言葉で説明できる🙂🛡️
  • 不変条件が壊れると何が起きるか、事故のイメージが持てる💥😱
  • 過去のバグを1つ、「不変条件が破れたせい」として言い換えられる📝✨

1) 不変条件ってなに?🌼

Intro Invariants

不変条件(Invariant)は、ざっくり言うと…

「そのデータ(状態)が“存在する限り”ずっと真でいてほしい条件」 🧷

たとえばこんな「絶対守りたい約束」だよ👇😊

  • 年齢は 0以上 🔢
  • 金額は マイナス禁止 💰🚫
  • メールは 空文字禁止 📧🚫
  • 期間は 開始日 <= 終了日 📅✅
  • 注文が「発送済み」なら 追跡番号が必須 📦🔍
  • 「課金済み」なら 支払い方法が確定してる 💳✅

ポイントはね… **「不正な値が“できちゃった後”に気づく」**より、 **「そもそも“作れない・入り込めない”」**ほうが強い💪✨


2) 不変条件が壊れると何が起きる?💥😵‍💫

不変条件が壊れると、バグってだいたいこうなるよ👇

事故パターンA:値が変(ゴミ値)🗑️

  • Price = -100 が入って、返金処理が暴走💸💥
  • Email = "" のまま登録されて、通知が全部落ちる📧❌

事故パターンB:状態が変(整合しない)🧩💥

  • 「発送済み」なのに追跡番号が空で、配送追跡ができない📦😇
  • 明細合計と請求合計がズレて、ユーザーから問い合わせが爆増☎️🔥

つまり… 「ありえない状態」がシステムの中に入ると、あとで高くつく 😭💸


3) “チェックする”と“守る”は別物だよ🛡️🚪

Check vs Protect

ここ、めっちゃ大事💡✨

  • チェックする:あとで「おかしい!」って見つける👀
  • 守る:そもそも「おかしい状態を作らせない」🔒✨

この教材のテーマはタイトル通り👇

  • 型で守る(不正な値が“表現しにくい”形にする)📦
  • 境界で守る(外から入る入口で弾く)🚪🛡️

まだ第1章だから、今はふわっとでOK🙆‍♀️🌸 「守るってそういう方向なんだ〜」が掴めれば勝ち🎉


4) ミニ例:会員登録で起きがちな事故📧💣

よくある「壊れる」例😇

メールアドレスが空でも通ってしまうと…

  • 登録は成功したように見える✅
  • でも後で「メール送信」のところで落ちる📧💥
  • さらに「誰のアカウントか追えない」みたいな二次被害も…🌀😵‍💫

“境界”で守る(入口で弾く)🚪🛡️

「フォーム入力」みたいな外部入力は、まず入口でチェックするのが基本✨

public static Result Register(string email)
{
if (string.IsNullOrWhiteSpace(email))
return Result.Fail("メールアドレスは必須です📧");

// ここまで来たら「少なくとも空ではない」✅
// さらに形式チェックや正規化は、後の章で強化していくよ🙂
return Result.Ok();
}

public readonly record struct Result(bool Success, string? Error)
{
public static Result Ok() => new(true, null);
public static Result Fail(string error) => new(false, error);
}

この段階の大事ポイントは👇

  • “まず入口で弾く”だけでも事故が激減すること😊🛡️
  • でも「内部のモデルが壊れない保証」までは、まだ弱い(次の章以降で強くするよ)💪✨

5) 演習:過去バグを「不変条件の破れ」に言い換えよう📝💗

ステップ1:過去バグを1個思い出す🧠💭

例:

  • NullReferenceException が出た
  • 合計金額がズレた
  • 二重登録された
  • ボタン連打で二重課金した などなど😵‍💫💥

ステップ2:「本当は何が“絶対真”であるべきだった?」を1行で書く✍️

テンプレこれ👇(使いやすいよ!)

  • 「〜のとき、◯◯は必ず△△である」
  • 「◯◯は△△してはいけない」
  • 「◯◯は常に△△の範囲に入る」

例にすると👇

  • 「ユーザーが存在するなら、Emailは空じゃない」📧✅
  • 「課金済みなら、PaymentIdが必ずある」💳✅
  • 「注文合計は、明細合計+税−割引と一致する」🧾✅

ステップ3:それは“どこで壊れた”?(入口?更新?状態遷移?)🗺️

今はざっくりでOKだよ🙂

  • 入力の入口(フォーム/API)で入った?🚪
  • 更新処理で壊れた?🔁
  • 状態が変わる瞬間(例:支払い→発送)で壊れた?🎭

6) AI活用:バグ文面を「不変条件で言い換え」させよう🤖✨

AIには、**“翻訳係”**をやらせるのがめちゃ便利だよ😊💕

コピペ用プロンプト🎁

以下のバグ説明を「不変条件(絶対守る約束)」の形に言い換えてください。
出力は次の形式で:
1) 破れていた不変条件(1〜5個)
2) どこで守るのが良さそうか(境界/内部/更新/状態遷移 など)
3) 再発防止のための最小の対策案(まず入口、その次に型)

--- バグ説明 ---
(ここに貼る)

さらに一歩進めたいならこれも追加👇🧪✨

  • 「この不変条件のテストケースを10個出して」
  • 境界値(ギリギリの値)を多めで」

7) チェッククイズ(超かんたん)🎀✅

Q1. 不変条件って一言でいうと?🙂 Q2. 不変条件が壊れると、どんな事故が起きる?💥 Q3. “守る”ってどういう方向の考え方?🔒

(答え例) A1. 「絶対守る約束」🛡️ A2. ゴミ値・整合崩れ・二次被害が起きる💣 A3. 「そもそも壊れた状態を作らせない」方向🔒✨


まとめ🌟

  • 不変条件=絶対守る約束🙂🛡️
  • 壊れると、値が変・状態が変で事故る💥😵‍💫
  • まずは 入口(境界)で弾くだけでも効果大🚪✅
  • これから 境界で、どんどん「壊れない設計」にしていくよ〜💪🎀

ちょい最新メモ(今のC#まわり)📌✨

  • C# 14 が最新で、.NET 10 上でサポートされてるよ📦✨ (Microsoft Learn)
  • Visual Studio 2026 には .NET 10 SDK が含まれる案内になってるよ🧰✨ (Microsoft Learn)
  • .NET 10 の “What’s new” で、C# 14 の更新点もまとまってるよ📚 (Microsoft Learn)
  • VS Code側も 2026年1月の Insiders 更新が出てる(更新日が明記されてる)よ📝✨ (Visual Studio Code)

次の第2章はね、「壊れた状態の例」をいっぱい出せるようになる回だよ👀💣 第1章の演習で書いた“過去バグ1個”が、そのまま第2章の材料になるから、ぜひメモ残しておいてね📝💕