第4章 まず覚える合言葉3つ 🗣️✨
![hex_ts_study_004[(./picture/hex_ts_study_004_isolation_of_the_domain.png)
この章はね、細かい図とか理屈より先に、一生モノの3つの合言葉を体に入れる回だよ〜😊💕 この3つさえ覚えておくと、あとでPort/Adapterを作るときに迷子になりにくいの!🧭✨
1) 合言葉その①「中心を守る🛡️」🏰💖
✅ 意味(超ざっくり)
アプリの中心(ルール)に、外の都合を入れないってことだよ🙂✨
- 中心:ルール(「空タイトル禁止」「完了は二重適用禁止」みたいな決まり)🧠
- 外側:UI/HTTP/DB/ファイル/日時/UUID…などの“入出力”🌐💾⏰
中心が外側の仕組み(Expressとかfsとか)を知り始めると、急に壊れやすくなる😵💫💥 だから 中心は静かに・強くが正義✨🛡️
✅ すぐ使えるチェックリスト ✅
中心のコードを見て、これが出てきたら黄色信号🚥😳
express/Request/Response(HTTPの匂い)🌐fs/path(ファイルの匂い)📄- DBのクライアント(sqlite/prisma/…)💾
new Date()(時間の匂い)⏰- 外部API SDK(Stripeとか)💳
出てきても即アウトじゃないけど、**「外に追い出せないかな?」**って考えるクセが大事だよ😊✨
2) 合言葉その②「約束はPort🔌」📌✨
✅ 意味(超ざっくり)
中心が“外側にお願いしたいこと”を、インターフェースとして宣言するのが Port だよ🔌💕
ポイントはここ👇 Portは中心側の言葉で書く(外側の技術の言葉に寄せない)🧠✨
たとえば「ToDoを保存したい」って中心が思ったら、中心はこう言うの👇
// core(中心)側:外にお願いする“約束”=Port 🔌
export interface TodoRepositoryPort {
save(todo: { id: string; title: string; completed: boolean }): Promise<void>;
findAll(): Promise<Array<{ id: string; title: string; completed: boolean }>>;
}
これが 「約束はPort🔌」 の正体だよ😊✨
🌿 Portを“最小の約束”にするコツ ✂️
- メソッド数を増やしすぎない(増えると管理地獄👻)
- 「今必要なこと」だけに絞る(未来の妄想で盛らない🙅♀️)
- 名前は 中心の目的に寄せる(
PrismaTodoRepositoryみたいな技術名はPortに入れない)🧠✨
3) 合言葉その③「変換はAdapter🧩」🔁✨
✅ 意味(超ざっくり)
Adapterは、外側の世界を“中心に合わせる”変換係だよ🧩💕
- 外側の面倒(JSON/DB行/HTTP入力/例外/型の違い)を吸収する
- 中心の約束(Port)を満たすように実装する
例:さっきの TodoRepositoryPort を、メモリ配列で実装するAdapter👇
import { TodoRepositoryPort } from "../core/ports/TodoRepositoryPort";
// 外側(adapters)側:Portを満たす“実装”=Adapter 🧩
export class InMemoryTodoRepositoryAdapter implements TodoRepositoryPort {
private todos: Array<{ id: string; title: string; completed: boolean }> = [];
async save(todo: { id: string; title: string; completed: boolean }): Promise<void> {
const index = this.todos.findIndex(t => t.id === todo.id);
if (index >= 0) this.todos[index] = todo;
else this.todos.push(todo);
}
async findAll(): Promise<Array<{ id: string; title: string; completed: boolean }>> {
return [...this.todos];
}
}
🥗 Adapterは「薄い」が正義!
Adapterが太り始めると、中心が汚れていくの😱💦
AdapterにいてOK ✅
- 変換(外→中心のDTO、中心→外のレスポンス)🔁
- 外部呼び出し(DB/HTTP/FS)📡
- 外部の例外を“中心向けの形”に包む(ラップ)🎁
Adapterに入れちゃダメ🙅♀️
- 業務ルール(「タイトル空は禁止」みたいなやつ)🧠
- 状態遷移の判断(「完了を二重適用禁止」みたいなやつ)🚫
まとめ:今日の3語だけ覚えて帰ってね🎁💖
- 中心を守る🛡️(ルールは中心、外の都合を入れない)
- 約束はPort🔌(中心が欲しい外部機能を“契約”にする)
- 変換はAdapter🧩(外側を中心に合わせる“変換・実装係”)
この3つが頭にあるだけで、次の章以降(Port設計・Adapter実装)がめちゃラクになるよ😊✨
ミニ練習クイズ🎀(すぐ解けるやつ)
次のうち Port はどれ? Adapter はどれ?🧐✨
A. interface TodoRepositoryPort { ... }
B. class InMemoryTodoRepositoryAdapter implements TodoRepositoryPort { ... }
C. AddTodoUseCase(ユースケース)
✅ 答え
- Port:A 🔌
- Adapter:B 🧩
- 中心(アプリのルール側):C 🛡️
AI拡張の使いどころ(安全運転版)🤖🧠✨
AIに頼むときは、「中心を守る🛡️」を壊さない指示がコツだよ🙂✨
✅ そのままコピペで使えるプロンプト3つ📌
- Port案を出してもらう(でも最終判断は自分!)
- 「ToDoの保存と一覧に必要な最小のPortを、メソッド2〜3個までで提案して。技術名は禁止。中心の言葉で。」
- Adapter雛形を作ってもらう
- 「このPortを満たす InMemory のAdapter実装を作って。業務ルールは絶対に入れないで。変換と保存だけにして。」
- 汚染チェックをさせる
- 「この core フォルダのコードに、fs/express/DBクライアント/new Date が混ざってないかレビューして。混ざってたら移動案を出して。」
小ネタ:最近のTypeScript事情(知ってると気分が上がるやつ)✨
この教材で使う“Port=interface”みたいな基本はずっと安定だけど、TypeScript自体も進化中だよ〜🚀 たとえば TypeScript 5.9 系のリリース情報が出ていて、さらに **TypeScript 7(ネイティブ化の流れ)**の進捗も公式ブログで共有されてるよ🧑💻✨ (Microsoft for Developers) (「へぇ今そんな感じなんだ〜」くらいでOK😉💓)
次の章では、この合言葉を使って **「Portをどう切るか」**を実際にやっていくよ🔌✨ この3つ、今のうちに口に出して言えるようにしとこっ😊🛡️🔌🧩💕