第15章:総まとめ:よくある失敗・実務の落とし所・次の一歩🚀💖
ここまでで、ToDoミニアプリを使いながら CQS(Command / Query 分離)の「気持ちよさ」まで体験できたはず〜!🥳✨ この最終章は 「明日から実務で迷いにくくなる」 のがゴールだよ🧭💕
15-1. まずは“完成形の型”を1枚で🧩✨(迷子防止)

「CQS、わかった気がするけど…結局どんな形が正解?」ってなるよね😇 **超実務寄りの“ちょうどいい型”**はこれ👇
- Command:状態を変える(副作用あり)🔧 → 例:追加、完了、削除、名前変更
- Query:状態を読む(副作用なし)📖 → 例:一覧、検索、集計、表示用に整形
そして、依存関係ルール的には(ざっくり)こう👇 UI → アプリ層(Command/Query) → ドメイン の向きで依存するのが安全🧸🧱
15-2. 失敗トップ3😱(症状→原因→直し方)

🥇 失敗1:Queryが更新してる😱💥
ありがち症状
getTodos()の中で「ついでに最終アクセス日時を保存」してるgetTodos()の中で「キャッシュを更新」「ログをDBへ保存」してる
なにが困る?
- Queryのたびに状態が変わる → テストしにくい、バグが増える、キャッシュもしにくい😵💫
直し方(最短ルート)
- “ついで副作用”を Queryの外側へ追い出す(ラッパー / ミドルウェア)🚪✨
- どうしても時間が必要なら
Date.now()を直で呼ばず 引数で受け取る(再現性UP)⏰
おまけ(2026の最新TS事情と相性◎)
TypeScript 5.9 では tsc --init の初期設定がかなり“ガチ寄り”になってて、strict: true や noUncheckedSideEffectImports: true などがデフォで入る流れが強いよ(副作用に厳しめ)🧠✨ (TypeScript)
さらに import defer で「モジュールの副作用を遅らせる」方向の提案も進んでるから、“副作用コントロール”はこれからも重要テーマだよ〜🍃 (TypeScript)
🥈 失敗2:Commandが返しすぎ🎁🐘
ありがち症状
addTodo()が「更新後の一覧」を返してるcompleteTodo()が「画面表示用DTO」を返してる
なにが困る?
- Commandが “Queryの仕事” を奪う → 関心が混ざる → 変更に弱い😵💫
- 「更新ロジック」と「表示整形」が絡まって事故る💥
実務の落とし所(ここ超大事)⚖️✨ Commandが返してOKなのは、だいたいこのへん👇
- ✅ ID(新規作成したID)
- ✅ 成否(Result型とか)
- ✅ 最小限の情報(たとえば楽観ロック用の version とか)
返しちゃダメ寄り👇
- ❌ 更新後の一覧(=Query)
- ❌ 画面表示用の整形済みデータ(=Query)
鉄板パターン:
Command → Queryで再取得 🔁✨(わかりやすくて強い)
🥉 失敗3:分けたのに命名が微妙で読めない📛😇
ありがち症状
processTodo()とかhandle()とか “何やるの?”って名前- Queryなのに
updateとか Commandなのにgetとか混乱
直し方(命名テンプレ)
- Command:
addTodo,completeTodo,renameTodo,deleteTodo - Query:
getTodos,findTodos,getTodoDetail,countCompletedTodos
コツ
- Commandは「やること」=動詞が強い💪
- Queryは「欲しいもの」=get/find/list/count が安定🍯
15-3. “実務の落とし所”ベスト7🏢✨(やりすぎ防止)
CQSは「守りすぎて苦しくなる」と本末転倒😇 現場でよくある“許されライン”をまとめるね👇
- CommandがIDを返す ✅(むしろ便利)
- Commandが Result を返す ✅(成功/失敗が明確)
- Queryで軽い整形はOK ✅(表示用DTOへの変換など)
- Queryで“保存”は基本NG ❌(ログ保存・最終閲覧更新など)
- ログ/メトリクスは外側へ ✅(ラッパーでやる)
- 時間・乱数は引数で注入 ✅(テストが楽)
- 依存は内側へ向ける ✅(UIからドメインへ依存を流す)
15-4. CQS と CQRS は別物だよ⚖️(やりすぎ注意)
- CQS:1つのコードベースの中で「書く/読む」を混ぜない🧩
- CQRS:さらに踏み込んで「読み取りモデルと書き込みモデルを分ける(場合によってはDBも)」みたいな世界🌍
初心者の勝ち筋はこれ👇 まず CQSで事故率を下げる → 必要になったらCQRSを検討、でOK🙆♀️✨ (いきなりCQRSに行くと設計コストが重い…!😵💫)
15-5. 卒業チェックリスト✅🎓✨(PR前に見るやつ)
✅ CQSチェック
- Queryの中に保存/更新/送信がない?🙅♀️
- Commandが「一覧」や「表示用DTO」を返してない?🐘
- “ついで副作用”が混ざってない?(ログ、カウンタ、キャッシュ更新)👀
- 時間・乱数・グローバルに依存してない?(必要なら引数/注入)⏰🎲
✅ 命名チェック
- Commandは動詞が強い?(add/complete/delete…)🔧
- Queryは get/find/list/count で自然?📖
✅ 依存関係ルール(超ざっくり)🧱
- UIが直接DBやfetchを握ってない?(アプリ層に寄せる)🚪
- ドメインが外部事情(UI/DB/HTTP)に引っ張られてない?🧸
15-6. ミニ卒業制作🎮💖(20〜40分でできる!)
ToDoアプリにこの3つを足してみて👇(CQSが効きまくるやつ✨)
① 期限つきToDo📅
- Command:
setDueDate(todoId, dueDate) - Query:
getTodosDueSoon(now, days)
② フィルタ(未完了だけ表示)🔎
- Query:
getActiveTodos()
③ “完了を取り消す”↩️
- Command:
reopenTodo(todoId)
完成のコツ
- Commandは状態だけ変える
- 画面に出す形は Query 側で整える これだけでスッキリするよ〜🧼✨
15-7. AI(Copilot/Codex)を“最終章っぽく”使うプロンプト集🤖🪄
そのままコピって使えるやつ置いとくね💕
- 「この関数、Command/Queryどっち?理由も3つで」🧠
- 「このQueryに副作用が混ざる可能性を全部指摘して」👀
- 「このCommandが返しすぎてるなら、最小の戻り値に直して」🎁➡️🪶
- 「依存関係ルールを破ってそうな import を指摘して、直し案も」🧱
- 「Vitestで Query のテスト雛形を3ケース作って」🧪✨ ※Vitestは 4.x 系が主流で移行ガイドも更新されてるよ📌 (vitest.dev)
15-8. 次に学ぶと強いロードマップ📚✨(CQSの次の一歩)
CQSを覚えた人が伸びる順番、だいたいこれ💪💕
- SoC(関心の分離):混ざりを減らす基本🧼
- DI(依存を外から渡す):Commandのテストが楽になる📦
- テスタブル設計:Queryは簡単、Commandは副作用を囲う🧪
- エラーモデリング:失敗の設計で実務が安定する🧯✨
15-9. さいごに🎀(ここだけ覚えて帰ってOK)
- Queryは読むだけ📖(副作用ゼロが最強)
- Commandは変えるだけ🔧(返しすぎ注意)
- 迷ったら “Command→Queryで取り直す” 🔁✨
- 命名が半分📛(読めれば勝ち!)
ここまで来たら、もうCQS初心者卒業だよ〜🎓🥳💖 次は、どれ進める?✨(SoC / DI / テスタブル / エラーモデリング)