「不変条件(Invariants)を型と境界で守る」30章 詳細アウトライン🎀🛡️
第1章 はじめまして不変条件🌱✨
- ゴール:不変条件=「絶対守る約束」だと説明できる🙂
- 学ぶ:不変条件が壊れると起きる事故(値が変・状態が変)💥
- 演習:自分の過去バグを「不変条件の破れ」視点で1つ言語化📝
- AI:バグ文面をAIに渡して「不変条件で言い換えると?」🤖
第2章 “壊れた状態”を見つける練習👀💣
- ゴール:壊れた状態の例をサクサク出せる
- 学ぶ:空文字/負数/範囲外/null/整合しない組み合わせ🧨
- 演習:「会員登録」「注文」「課金」から壊れた状態を各5個ずつ列挙
- AI:列挙→AIに「抜けてる壊れ方ある?」ってチェック役をさせる✅
第3章 不変条件はどこで守る?“境界”の話🚪🧱
- ゴール:境界=入力の入口だと分かる
- 学ぶ:UI / API / DB / 外部I/O は全部「境界」になりうる🌐🗄️
- 演習:自分の想定アプリで境界マップを作る🗺️
- AI:プロジェクト構成を説明して「境界候補を列挙して」🤖
第4章 まずは入口を守る:ガード節(Guard Clauses)🛡️
- ゴール:入口で弾くコードが書ける
- 学ぶ:早期return、メッセージ、責務の集約📌
- 演習:入力チェックが散ってる想定コードを「入口1箇所」に寄せる
- AI:「ガード節に整理して」+「読みやすい順に並べて」🤖
第5章 入口で守る:Validationを“仕様”にする📜✨
- ゴール:検証ルールが仕様書みたいに読める
- 学ぶ:ルールの命名、エラーメッセージの粒度📣
- 演習:検証ルールを「箇条書き→コード」へ落とす
- AI:仕様箇条書きを渡して「テストケース候補も出して」🤖🧪
第6章 失敗の表現①:例外って何者?⚡😵💫
- ゴール:例外の役割を雑に使わない
- 学ぶ:例外=想定外/回復困難のサイン、投げどころ🏷️
- 演習:入力不正を例外で表す版を作って、扱いにくさも観察👀
- AI:「この例外は本当に例外?」ってレビューさせる🤖
第7章 失敗の表現②:Result/戻り値で失敗を返す🧾🙂
- ゴール:ユーザー入力の失敗を安全に扱える
- 学ぶ:成功/失敗の分岐、エラー情報の持ち方📦
- 演習:同じ処理をResult型(自作でOK)で書き換える
- AI:「Resultの型設計を3案」出して比較🤖⚖️
第8章 失敗の表現③:境界で“変換”する🚪🔁
- ゴール:内部の失敗を外向け表現に変換できる
- 学ぶ:内部(ドメイン)と外(UI/API)の言葉を分ける🗣️
- 演習:内部エラー→画面表示/HTTPレスポンスに変換する関数を用意
- AI:「変換の責務分割(どこが何をする?)」を提案させる🤖
第9章 “型で守る”入門:ifチェック地獄から卒業🎓✨
- ゴール:型=安全な箱、の感覚を掴む📦
- 学ぶ:プリミティブ(string/int)のままが危険な理由😱
- 演習:
Email/Money/UserNameどれかを型にしたい理由を書く - AI:「型にすると何が嬉しい?」を短文でまとめさせる🤖
第10章 不正な値を作らせない:Factoryで生成を集中🏭🔒
- ゴール:new禁止ゾーンを作れる
- 学ぶ:private ctor +
Create(...)の型守りパターン🧷 - 演習:
Email.Create(string)を作って、失敗も返せるようにする - AI:「命名候補(TryCreate/Create/From)」を出してもらう🤖
第11章 値オブジェクト(Value Object)①:Moneyを作る💰💎
- ゴール:VOの基本(値で同一性)を体験
- 学ぶ:通貨+金額、丸め、比較、加算/減算のルール📌
- 演習:
Moneyを record で実装(不変)+不変条件を組み込む - AI:「Moneyの落とし穴(負数OK?小数?)」を洗い出し🤖🔍
第12章 値オブジェクト②:Email/文字列VOを作る📧💎
- ゴール:文字列VOで形式・長さを守れる
- 学ぶ:正規表現の扱いは“ほどほど”でOK(KISS)🙂
- 演習:
Email(形式+正規化:trim/lower等)を決める - AI:「正規化ルール案」→あなたが採用判断✅🤖
第13章 値オブジェクト③:期間(DateRange)を作る📅💎
- ゴール:開始<=終了の不変条件を型で固定
- 学ぶ:タイムゾーン注意、日付と日時の分離⏰
- 演習:
DateRange.Create(start,end)で逆転を防ぐ - AI:「境界値(同日/跨日/うるう年)」を出してもらう🤖🧪
第14章 record / immutable を味方にする❄️🧊
- ゴール:途中で壊れないデータ構造を増やす
- 学ぶ:immutable=変更ではなく“新しく作る”発想🔁
- 演習:mutable DTO→内部はimmutableへ変換する流れを作る
- AI:「immutableにすると何が楽?」をレビューコメント風に生成🤖
第15章 Nullable参照型でnull事故を減らす🚫null🧷
- ゴール:nullを“許す場所”を境界に限定
- 学ぶ:nullable警告の意味、
?の感覚🙂 - 演習:nullを受け取るのはDTOだけ、内部はnon-null前提に整理
- AI:警告ログを貼って「最小コストで直す案」🤖🛠️
第16章 不変条件パターン①:数値(範囲・丸め・単位)🔢📌
- ゴール:数値系ルールをテンプレ化
- 学ぶ:最小/最大、丸め、単位混在の事故(円とドル等)💸
- 演習:年齢/ポイント/在庫数などを型+ルールで守る
- AI:「数値系の境界値テスト」を大量生成させる🤖🧪
第17章 不変条件パターン②:文字列(長さ・禁止文字・形式)🔤📌
- ゴール:文字列の“ゆるさ”を減らす
- 学ぶ:空白、全角半角、トリム、正規化🧼
- 演習:
UserNameVO を作り、禁止ルールを入れる - AI:「ありがちな抜け(先頭空白とか)」を指摘させる🤖👀
第18章 不変条件パターン③:日付/時刻(期限・営業日・TZ)⏰📌
- ゴール:日付系事故を減らす
- 学ぶ:UTC/ローカルの混同、締切の解釈🌀
- 演習:期限(Deadline)をVO化して“過去禁止”等を組む
- AI:「日付の罠リスト」を作らせてチェックリスト化🤖✅
第19章 集合の不変条件①:重複禁止・上限・順序👥🧺
- ゴール:Listでも壊れない設計ができる
- 学ぶ:同一ID重複、最大件数、並び順の意味📌
- 演習:CartItemsで「同一商品は1行にまとめる」ルール実装🛒
- AI:「集合の不変条件パターン」を例付きで出してもらう🤖
第20章 集合の不変条件②:関連の整合性(合計金額など)➕🧾
- ゴール:部分と全体の整合を守れる
- 学ぶ:合計=明細の和、割引、税、丸めの順序💡
- 演習:Cartの
Totalが必ず整合するように更新経路を固定 - AI:「整合性が壊れる更新パターン」を列挙させる🤖💥
第21章 更新で壊れない①:setterを減らす✂️🔒
- ゴール:
public set;地獄を避ける - 学ぶ:更新はメソッド経由、カプセル化の意味📦
- 演習:プロパティのsetterを削って、更新メソッドに移動
- AI:「setter削減リファクタ案」を出させる🤖🛠️
第22章 更新で壊れない②:メソッドが“入口”になる🛡️🚪
- ゴール:更新メソッドで不変条件を守れる
- 学ぶ:
ChangeEmail(...)の中で検証→適用 の順✅ - 演習:更新メソッドにガードを入れ、無効状態を作れないようにする
- AI:「この更新、どんな不変条件が関係する?」を質問🤖
第23章 状態と不変条件①:状態って何?🎭✨
- ゴール:状態で“許可される操作”が変わると理解
- 学ぶ:Draft/Paid/Shipped…みたいな段階の考え方📦
- 演習:注文の状態を3〜5個決めて、できる操作を書き出す
- AI:「状態候補と意味」を提案させる🤖💡
第24章 状態と不変条件②:状態遷移表を作る📋🖊️
- ゴール:遷移を表にできる
- 学ぶ:イベント、許可/禁止、例外的遷移🚫➡️✅
- 演習:状態遷移表(テキストでOK)を作る
- AI:「遷移の抜け」をチェックさせる🤖🔍
第25章 状態と不変条件③:遷移時チェックを実装✅🔁
- ゴール:遷移の瞬間に壊れない
- 学ぶ:ガード条件、遷移メソッドの作法🛡️
- 演習:
Pay()/Ship()などの遷移メソッドで条件を保証 - AI:「ガード条件の命名案」を出してもらう🤖🏷️
第26章 境界で守る①:UI入力→内部モデルへ🎀➡️🏛️
- ゴール:DTOはゆるく、内部は堅く
- 学ぶ:文字列入力→VOへ変換、失敗の見せ方🙂
- 演習:フォーム入力→コマンド→VO変換→処理 の流れを作る
- AI:「入力項目ごとの検証ルール表」を生成🤖🧾
第27章 境界で守る②:API(Web)入口の置き方🌐🚪
- ゴール:Controllerを薄くできる
- 学ぶ:Controller=受けて渡す、検証・変換は別へ📦
- 演習:API処理を「受信/検証/変換/実行」に分割
- AI:「薄いControllerテンプレ」を作ってもらう🤖
第28章 境界で守る③:外部API/DBの“汚れ”を中に入れない🧼🧱
- ゴール:外部の癖を隔離できる
- 学ぶ:変換層(翻訳)の考え方、命名・欠損値の吸収🧯
- 演習:外部DTO→内部VOへ変換するAdapterを1つ作る
- AI:「変換層で吸収すべき差」をリスト化🤖✅
第29章 DB制約は“最後の砦”🏰🗄️
- ゴール:アプリ+DBで二重に守る感覚を掴む
- 学ぶ:NOT NULL / UNIQUE / CHECK / FK の役割と限界📌
- 演習:不変条件一覧→「DBで守れる/守れない」を分類して対応表作成
- AI:「DB制約に落とせる条件」を提案させる🤖🧠
第30章 仕上げ総合演習:不変条件の壁を完成🏁🎉
-
ゴール:入口・型・更新・状態・DB・テストが一本につながる
-
学ぶ:最小完成(KISS)+重要度で厚くする(YAGNI回避)⚖️
-
演習:ミニ題材(例:会員登録+サブスク課金)で
- 不変条件一覧 → 2) VO/状態 → 3) 境界変換 → 4) テスト → 5) DB制約 の順で完成
-
AI:AIは「案出し係」+「テストケース大量生成係」🤖🧪✨
もし次に進めるなら、めちゃ実用的なのはこれ👇😊
- この30章のうち、**第10〜第13(VOの連続)**を「教材として気持ちいい流れ」にするために、**共通の題材(例:サブスク課金)**で統一して、各章の演習が積み上がるように整える📈✨
やるなら、題材は「会員+課金」「注文+配送」「予約+キャンセル」どれが好み?🥰🎀