第04章:「中心(ロジック)」と「外側(I/O)」モデル🏠➡️🌍

この章はね、頭の中に“設計の地図”を作る回だよ🗺️✨ ここがスッ…と入ると、あとで I/O を外に押し出す作業(分離)がめちゃラクになる😊💕
1) 今日のゴール🎯✨
章が終わったら、こんなことができるようになるよ👇
- どんな処理でも「中心(ロジック)」と「外側(I/O)」に分けて考えられる🧠✨
- 「境界(インターフェース)」って何かを説明できる📌
- コードを見て「これは中心?外側?」をラベル付けできる🏷️
- “矢印(依存の向き)”のルールが分かる➡️✅
2) まずは超ざっくり地図🗺
️🏠➡️🌍### ✅ 2つに分けるだけで世界が変わる🌈* **中心(ロジック)
🏠**:計算・判断・ルール(= 仕様のコア)
-
例:料金計算、割引、在庫チェック、入力の整形、判定ロジック…
-
外側(I/O)🌍:外の世界とのやりとり(= 変わりやすいもの)
- 例:HTTP、DB、ファイル、時刻、乱数、環境変数、ログ…
イメージはこんな感じ👇
🌍 外側(I/Oの世界) 🏠 中心(ロジック)
┌──────────────────┐ ┌──────────────────┐
│ fetch / DB / FS │ ---> │ 料金計算・判定 │
│ Date / Random │ │ 文字列整形 etc │
│ process.env / log │ │ (できれば純粋) │
└──────────────────┘ └──────────────────┘
↑ ↑
変更が多い😵💫 変更は仕様だけ😊
3) “境界”ってなに?🚪
📌(ここが超重要!)中心と外側の間には、境界線があるよ✂️✨ この境界をまたぐときに使うのが interface(最小の約束) 💍
✅ 境界(インターフェース)
の役割* 中心から見ると「外側の都合」を知らなくていい🙈✨
- 外側は「中心が欲しい形」に合わせて頑張る💪😆
- テストでは、外側を“ニセモノ”に差し替えられる🧸🧪
4) 依存の向き(矢印ルール)
➡️✅ここ、1回で覚えちゃおう😆✨
✅ ルール:矢印は“中心に向かう”🏠* 中心は外側の具体を知らない(fetch とか Date とか触らない)
🙅♀️
- 外側が中心に合わせる(アダプタが頑張る)🔧
OK✅: 外側 ---> 境界(interface) ---> 中心
NG❌: 中心 ---> fetch / DB / Date / process.env
5) 例で体感しよ🍩💰
(中心と外側を分ける)題材:クーポン付きの合計金額🧾✨
🏠 中心(純粋ロジック)
例* 入力:商品リスト、クーポン情報
- 出力:合計金額
- 外部に触れない(I/Oなし)✅
type Item = { name: string; price: number; qty: number };
type Coupon = { type: "percent" | "yen"; value: number } | null;
export function calcTotal(items: Item[], coupon: Coupon): number {
const subtotal = items.reduce((sum, it) => sum + it.price * it.qty, 0);
if (!coupon) return subtotal;
if (coupon.type === "percent") {
return Math.floor(subtotal * (1 - coupon.value / 100));
}
return Math.max(0, subtotal - coupon.value);
}
↑ これ、テストが超ラクになる予感しない?😆🧪✨ 「中心」はこういう データ入れて→結果が返る が理想だよ🍰💕
🌍 外側(I/O)
側の例(ここが変わりやすい)* クーポンをAPIから取る
- 商品をDBから取る
- 結果を画面やログに出す
この章では“実装”よりも、ここが外側だって気づけるのが大事だよ👀✨
6) ハンズオン:図を描く練習🖊️
🗺️(超だいじ!)### ステップ1:題材を1つ選ぶ🎲✨
どれでもOK👇
- ログイン判定(期限切れチェック)🔐
- 文字列整形(名前の整形、郵便番号の整形)📝
- 料金計算(割引、送料、税)💰
ステップ2:中心と外側を箱で描く📦テンプレ👇(まずはコピペして埋めるだけでOK!
)
【中心🏠】(ルール・計算・判断)
- 例:____________________________________
【外側🌍】(I/O・外部依存)
- 例:____________________________________
- 例:____________________________________
【境界🚪】(中心が欲しい“最小の約束”)
- 例:____________________________________
ステップ3:「I/Oっぽい単語」を見つけたら外側に置く👃
💨見つけたら即外側!🚨
fetch/ HTTP / API- DB / SQL
- ファイル読み書き
Date/ 時刻- 乱数
process.env- ログ出力
7) “境界”の作り方の感覚(最小でOK)
✂️📜境界はね、欲張ると一気に崩れるの🥺💦 コツはこれ👇
- ✅ 中心が本当に必要な操作だけにする
- ✅ 返す型は「中心が扱いやすい形」を意識する
- ✅ 外側の都合(HTTPレスポンスそのまま等)を漏らさない
8) AI活用ミニコーナー🤖🎀(境界の練習に最高!
)AIにお願いする時は、「中心/外側/境界」を言葉で縛ると良いよ✨
👍 良いプロンプト例* 「次の仕様を、中心(純粋ロジック)
と外側(I/O)に分けて、境界(interface)案も出して。中心は fetch/Date/env/log を触らないで」
👎 ダメになりがち例* 「実装全部作って」
→ だいたい中心がI/Oまみれになって戻ってくる😇💥
9) 最新事情メモ🆕📝
(この章の“背景”になる現実)設計の考え方自体は普遍なんだけど、外側(I/O)は特に変化が速いのがポイントだよ🌀 たとえば最近だとこんな動きがある👇
- TypeScript は 5.9 のリリースノートが 2026-01-12 に更新されてるよ🧠✨ (TypeScript)
- Node.js は v24 系が Active LTSとして扱われていて、セキュリティリリースも継続的に出てるよ🔒🛡️ (Node.js)
- テスト周りだと Vitest 4.0 が 2025-10 に登場して、移行ガイドも更新されてるよ🧪⚡ (Vitest)
- TypeScript は **ネイティブ化(TypeScript 7 “native preview” など)**の話も進んでて、速度改善が大きいテーマになってるよ🚀 (Microsoft Developer)
だからこそ、変わりやすい外側を中心から隔離しておくと、変更が怖くなくなるんだよね😊✨
10) まとめ🍀
✨(今日の合言葉)* 🏠 中心=ルール(なるべく純粋)
- 🌍 外側=I/O(変わりやすい)
- 🚪 境界=interface(最小の約束)
- ➡️ 依存の矢印は中心へ向ける
次の章(第5章)で、いよいよ「この地図をそのままフォルダ構成・最小プロジェクト」に落としていくよ📁✨ その前に、今日のハンズオンの「箱3つテンプレ」、1個だけでも埋めてみてね〜😆🖊️💕