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

第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" 👻 → 外側(謎コード)
  • MoneyPoint 💴✨ → 内側(ルールがある)
  • 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_kbnStudentType
  • null → 内側では扱える形に(例:空文字にしない、必須なら弾く)✅

② 防ぐ🛡️🚫

  • 「変な値」「未知コード」「欠損」を内側へ入れない
  • 外側の変更があっても、まず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) だからこそ、型で境界を守る設計はますます大事になる〜🧷💪