ヘキサゴナル(Ports & Adapters)35章 詳細アウトライン 🔷🔌✨
(前提:TS初中級/設計超入門/Windows+VS Code/AI拡張あり🤖✨)
第1章 この章のゴール宣言 🎯✨
- できるようになること(Port/Adapterを説明できる、中心を守れる)
- 今日のゴールアプリ(小さく作って育てる方針)🌱
- つまずきポイント予告(概念→体験→整理の順)😊
第2章 直結コードの「つらさ」あるある 😵💫💥
- UI/DB/HTTPが混ざると起こる悲劇(修正が怖い、テスト不可)
- “なぜ怖いのか”=依存が散らばるから🧨
- 直結のミニ例(読みにくい例を一瞬見せる)👀
第3章 ヘキサゴナルの1枚絵(城の中心を守る)🏰🛡️
- 中心=ルール(ユースケース/ドメイン)
- 外側=I/O(UI、DB、外部API)
- 六角形は「比喩」でOK、形が重要じゃない🙆♀️
第4章 まず覚える合言葉3つ 🗣️✨
- 「中心を守る🛡️」
- 「約束はPort🔌」
- 「変換はAdapter🧩」
第5章 Portってなに?(差し込み口=約束)🔌😊
- interfaceの役割(中心が求める契約)
- Portが増えすぎると死ぬ話(予防線)⚠️
- “最小の約束”にするコツ✂️
第6章 Adapterってなに?(変換器=実装)🧩✨
- 外部世界の都合を吸収する係
- Adapterは「薄い」が正義🥗
- 太ると中心が汚れる理由😱
第7章 Inbound / Outbound の超やさしい整理 🚪➡️⬅️
- Inbound:外→中(画面/HTTP/CLI)
- Outbound:中→外(DB/外部サービス)
- “中心がPortを持つ”の基本ルール📌
第8章 依存の向き(これだけは最重要)🧭🔥
- 中心は外側を知らない🙅♀️
- 外側は中心を知っていい👌
- 依存が逆転すると何が嬉しい?(差し替え・テスト)🔁🧪
ここから実作業:ミニアプリで体験するよ😊💻
第9章 今回の題材を決める(ToDoミニ)📝🍰
- 機能:追加・一覧・完了✅
- ルール:タイトル空は禁止、完了は二重適用禁止など🚫
- “I/O後回し”の理由(まず中心から)💖
第10章 Windows+VS Code準備①:プロジェクト作成 🪟📦
- Node環境確認(Windowsでの確認手順)
- npm/pnpmどちらでもOK(教材はnpm基準でも可)✅
- 「起動して動く」までの最短ルート🚀
第11章 Windows+VS Code準備②:VS Codeの必須設定 🧰✨
- 保存時整形・自動import・検索の使い方
- よくある詰まり(パス、改行コード等)😵
第12章 Windows+VS Code準備③:AI拡張の準備 🤖💖
- Copilot/Codexの使いどころ(雛形・命名・テスト案)
- 使っちゃダメなとこ(設計の芯をAI任せにしない)⚠️
- “AIレビューの質問テンプレ”を配布📌
第13章 TypeScript設定①:strict最小セット 🛡️✨
- 「何を守ってくれるか」を超短く
- 初心者が辛くならないバランス
- “型のエラーは味方”の感覚づくり😊
第14章 TypeScript設定②:品質の土台(Lint/Format/Test)🧹🧪
- 目的:読みやすさ統一&事故防止
- “機械に任せること”を増やす🤖✨
第15章 フォルダ構成を固定(迷子防止)📁🧭
- domain / app / adapters の3点セット
- importルール(中心→外側に向かない)
- 命名のコツ(Portは〜Port/Repository、Adapterは〜Adapter)✨
中心(ドメイン&ユースケース)を作る🧠❤️
第16章 ドメイン入門①:ドメイン=ルール置き場 🏠📌
- 「データ」じゃなく「ルール」が主役
- ルールをControllerに置くと起きる事故😱
第17章 ドメイン入門②:最小モデル(Todo)を作る 🧩📝
- Todoの構造(id/title/completed)
- 不正状態を作らない工夫(生成時チェック)🚫
第18章 ドメイン入門③:ミニ不変条件(Invariants)🧷✨
- タイトル空NG
- 完了の二重適用NG(状態遷移の芽)🌱
第19章 ユースケース入門①:アプリの中心って何? 🎮➡️🧠
- AddTodo / CompleteTodo / ListTodos の責務
- ユースケースは「手順」と「判断」を持つ📌
第20章 ユースケース入門②:入力・出力の形(DTO)📮📤
- “外に見せる形”はシンプルに
- domain型を外に漏らさない(将来守れる)🛡️
Port(約束)を決める🔌✨
第21章 Inbound Port:UseCaseの入口を決める 🚪🔌
- 何を受け取り、何を返すか
- 入力チェックの置き場所の方針(境界でやる)📌
第22章 Outbound Port:Repositoryを決める 💾🔌
- 保存・取得の最小インターフェース
- “なんでもRepository”にしない注意⚠️
第23章 Outbound Port:Clockなど小さな外部依存を切る ⏰🔌
- 「時間」「UUID」「通知」などを外に逃がす
- テストが急に楽になる魔法🧪✨
Adapter(実装)で動かす🧩🚀
第24章 Inbound Adapter①:CLIで最速成功⌨️🎉
- ユースケースを呼ぶだけの薄い入口
- まずは「動く!」を作る💖
第25章 Inbound Adapter②:CLIの入力→DTO変換 🔁⌨️
- parse/validateは入口側で
- 中心に文字列処理を持ち込まない🙅♀️
第26章 Outbound Adapter①:InMemoryRepository 🧠📦
- 配列で保存(爆速で理解できる)
- 差し替え可能性を体感🔁✨
第27章 Outbound Adapter②:FileRepository(JSON保存)📄💾
- Windowsでも扱いやすい保存先
- 失敗(読み取り不可等)を経験して学ぶ😳
第28章 Adapterが薄いかチェック(太ったら負け)🥗⚠️
- 禁止:業務ルール、状態遷移、巨大if
- OK:変換、呼び出し、例外のラップ🔁
Web化(HTTP)で「入口の差し替え」を体験🌐✨
第29章 HTTP導入①:ルーティング→ユースケース呼ぶだけ 🚪🌐
- Controllerは薄く!
- 入口は“翻訳係”に徹する🧩
第30章 HTTP導入②:Request→DTO変換、Response整形 🔁📮
- バリデーションは入口で
- エラーもレスポンスに変換する準備📌
第31章 HTTP導入③:ユースケースはHTTPを知らない🙅♀️
- 中心コードが1行も変わらないことを確認✅
- ここがヘキサゴナルの気持ちよさ😊💕
テスト・エラー・組み立て(実務の肝)🧪🧩🚧
第32章 テスト①:ユースケース単体テスト(最優先)🧪💪
- InMemory差し替えで高速テスト
- 期待:仕様が文章みたいに読める✨
第33章 エラー設計①:中心のエラー(仕様)📌😌
- DomainError / ValidationError の考え方
- “例外で投げ散らかさない”方針🧯
第34章 エラー設計②:外側のエラー(I/O失敗)😵💫
- File読めない、ネット落ちる、など
- 外側でログ&再試行方針(軽く触れる)🔁
第35章 Composition Root:依存の組み立て(合体場所)🧩🏗️
- newする場所を1か所へ
- 本番:FileRepo、テスト:InMemoryみたいに切替✨
- “差し替え戦略”の定番パターンを紹介🎁
おまけ(でも超重要)🤖📊⚠️
第36章 観測ちょい入門:ログをどこに置く?🪪📊
- 相関IDってなに?(ざっくり)
- Adapterでログ、中心は静かに🧠✨
第37章 AI活用①:雛形生成の安全な頼り方 🤖🧰
- 生成してOK:Adapter雛形、テスト雛形
- 要注意:Port設計と依存の向き(AIが崩しがち)⚠️
第38章 AI活用②:レビュー用プロンプト集(そのまま使える)📝🤖
- 「Adapter薄い?」
- 「中心が外部型を参照してない?」
- 「Port大きすぎない?」
- みたいなチェック質問テンプレ✅
第39章 アンチパターン①:中心がHTTP/DB型を知っちゃう 😱
- 症状:domainにRequest/Response、ORMモデル混入
- 修正:DTO/変換をAdapterへ押し出す🔧
第40章 アンチパターン②:巨大Port/太いAdapter 🐘🍔
- Portは“必要最小限”が基本
- Adapterが肥大化したら「変換」「呼び出し」以外を追放🏃♀️
第41章 アンチパターン③:Repositoryが何でも屋になる 🧹😵
- なんでも入れると境界が死ぬ
- UseCaseの言葉に寄せて分割するコツ✂️✨
第42章 直し方テンプレ:分解の手順書 🔧📌
- ①混ざってる責務を発見
- ②Portにする約束を最小化
- ③Adapterへ移動(変換だけ残す)
- ④テストで守る🧪✨
第43章 まとめ:今日の合言葉3つ(再掲)🎁💖
- 中心を守る🛡️
- 約束はPort🔌
- 変換はAdapter🧩
第44章 次の一歩:クリーンアーキとの関係&次章への橋渡し 🌉✨
- ヘキサゴナル=Ports & Adapters
- クリーンアーキ=依存方向の徹底(親戚)👪
- 「次に学ぶと良いもの」案内🚀
第45章 自主課題(提出形式まで)📝🎀
- 課題A:RepositoryをDB版に差し替え(中心無修正で)🔁
- 課題B:通知(メール/Slackの代わりのダミー)Port追加📨
- 課題C:状態追加(Pending→Doneなど)で状態機械の入口へ🚦