第4章:設計が超入門でもOKな「境界」と「関心の分離」🚪🧱
この章でできるようになること 🎯✨
- 「内側(自分のルール)」と「外側(相手の都合)」をスパッと分けて考えられるようになる🧠💡
- SoC(関心の分離)を“難しい言葉なし”で説明できるようになる🧁📚
- ACL(腐敗防止層)が どこに置かれて、何を守るのか をイメージできる🌊🛡️
1) まずSoC(関心の分離)ってなに?🍰🧩
SoCはひとことで言うと、
「役割ごとに場所を分けて、混ぜない」 ってことだよ〜!😊✨
たとえば…学園祭の屋台で考えるとわかりやすい🍟🎪
- 👩🍳 キッチン:料理を作る(おいしさ=ルールが大事)
- 💁♀️ レジ:お金を受け取る(支払いの手順が大事)
- 📣 呼び込み:お客さんに説明する(見せ方が大事)
ここが全部ごちゃ混ぜだと… 「料理の途中でレジ対応」「呼び込みしながら揚げ物」になって事故る😱🔥

プログラムも同じで、
- ✅ ビジネスのルール(内側)
- ✅ 外部API・DB・UI(外側)
- ✅ 変換・翻訳(境界)
を混ぜないほど、壊れにくくなるよ〜🧱✨
2) 「境界」ってなに?🚪✨
境界は、ざっくりこの線引き!✍️
-
🏠 内側(自分のルール) アプリの“こうあるべき”が詰まってる場所 例)ポイントは0以上、学食ポイントの加算/減算のルール🍱➕➖
-
🌍 外側(相手の都合) 外部API、DB、HTTP、日付フォーマット、謎のコード値… 例)
stu_kbn: "1"とか、amount: "001200"とか👻
ここで大事なのが、
外側のクセを、内側に持ち込まない! 🧼🚫

3) 「外側のクセ」が内側に入ると何が起きるの?😇🕳️
外側って、だいたいこんなクセがあるよね💦
- 🧾 命名が独特(
stu_kbn,payFlg,s_id) - 🔤 コード値が謎(
"1"|"2"|"9") - ❓ 欠損やnullが混じる
- ⏱️ 日付が文字列で来る(タイムゾーンも謎)
- ⚠️ 仕様変更が突然来る(項目増える/意味変わる/形式変わる)
これを内側でそのまま使い始めると…
- 内側のコードが「外部APIの方言」で汚れていく😵💫
- 外部がちょっと変わっただけで、内側が連鎖的に壊れる💥
- テストが「外部仕様の再現ごっこ」になってつらい🧪💦
この“汚れていく感じ”が、いわゆる 腐敗(Corruption) のイメージだよ🧼🫠
4) だからACL!「通訳+防波堤」🌊🛡️
ACL(Anti-Corruption Layer)は、境界に置く 通訳さん だよ〜🗣️✨ 外側の言葉(DTOやレスポンス)を、内側の言葉(ドメイン型)に翻訳する📘➡️📗
イメージ図はこんな感じ👇😊
**ポイントはこれ!**👇💡
- ✅ 内側は「自分の用語」と「自分のルール」だけで暮らす🏠✨
- ✅ 外側の変更は、まずACLで吸収する🧽
- ✅ “境界”があると、変更に強くなる🧱
5) 「内側=自分のルール」「外側=相手の都合」ってどう見分ける?🔍✨
迷ったらこの質問をしてみてね😊
質問A:それって “アプリの本質” ?🧠
- YES → 内側
- NO(相手の都合っぽい) → 外側
質問B:相手が変えたら自分も変わる?🌪️
- YES → 外側(境界で止めたい!)
- NO(自分の都合で決める) → 内側
例でやってみよ〜🧁
studentType: UNDERGRAD | GRAD🎓 → 内側(意味が明確)stu_kbn: "1" | "2"👻 → 外側(謎コード)MoneyやPoint💴✨ → 内側(ルールがある)HTTP 429(レート制限)🌩️ → 外側(通信の都合)
6) TypeScriptだと「境界」を型で固定できるのが強い💪🧷
境界を守るコツは、型で門番を作ること🚪🔒
✅ 外側の型(DTO)と、内側の型(ドメイン)を分ける
- 外側:APIが返す形(変わりやすい)📦
- 内側:自分が使いたい形(安定させる)📘
例(超ミニ)👇
// 外側(DTO): APIの都合そのまま
export type StudentDto = {
s_id: string;
stu_kbn: "1" | "2"; // 謎コード👻
name: string | null;
};
// 内側(ドメイン): 自分の都合(意味がある言葉✨)
export type Student = {
id: StudentId;
type: StudentType;
name: string;
};
export type StudentId = string & { readonly __brand: "StudentId" };
export type StudentType = "UNDERGRAD" | "GRAD";
ここで「DTOを内側に持ち込まない」だけで、めっちゃ平和になる☺️🌸
7) ACLがやること(この章バージョン)🧱✨
第4章時点では、ACLの仕事はこの2つだけ覚えればOKだよ😊
① 翻訳する🗣️➡️📘
stu_kbn→StudentTypenull→ 内側では扱える形に(例:空文字にしない、必須なら弾く)✅
② 防ぐ🛡️🚫
- 「変な値」「未知コード」「欠損」を内側へ入れない
- 外側の変更があっても、まずACLで止める
8) ミニ演習:これ、内側?外側?どこに置く?🧠💬
演習①(判定)🔍
次のうち「内側」っぽいのはどれ?(複数OK)✨
- A)
HTTP 500 - B)
ポイントは0以上 - C)
stu_kbn: "1" - D)
残高不足
✅答え:BとDが内側!AとCは外側〜🌍
演習②(置き場所)📦
「外部APIの amount: "001200" を number にする処理」はどこ?
- ✅ ACL(外側→内側へ入る前の整形)🧽✨
演習③(設計の一言)📝
次のルールを1文で言ってみてね☺️
「外部DTOは内側に持ち込まない」
例)
- 「内側はドメイン型だけで話す。外の言葉はACLで翻訳する。」🛡️✨
9) AI(Copilot/Codex系)を使うときの“境界ガード”🧯🤖✨
AIはめっちゃ便利だけど、油断すると 境界を越えて混ぜがち 😇💦 だから、AIに頼むときは「境界を守る指示」が超大事!
使いやすいお願いテンプレ(例)🪄
- 「外部DTOとドメインモデルを分けて、変換関数だけ作って」🔁
- 「DTOをドメインに変換する mapper を作って。ドメイン側はDTOをimportしないで」🚪🔒
- 「未知コードが来たときの方針も含めて提案して」🤔🧾
VS CodeのCopilotは、コード補完だけじゃなく説明や実装の提案もできるよ。(Visual Studio Code)
10) まとめ:この章の合言葉🧼🧱✨
- SoC = 役割を混ぜない 🧩
- 内側 = 自分のルール 🏠
- 外側 = 相手の都合 🌍
- ACL = 通訳+防波堤 🗣️🛡️
そして最大の合言葉はこれっ👇💖
「外側のクセは、境界(ACL)で止める!」 🚪🧯✨
ちょい豆知識(最新動向)🫘✨
TypeScriptは 6.0 を“橋渡し(bridge)”として、より高速化を狙う 7.0 系へ進む方針が公開されているよ(6.1は出さない予定、必要ならパッチのみ)。(Microsoft for Developers) だからこそ、型で境界を守る設計はますます大事になる〜🧷💪