Vibe Coding Handbook

実装・アーキテクチャ判断ハンドブック

シングルトン、モノリス、マイクロサービス、CQRS、SSR、SLO など、実装判断で頻出する概念を 「いつ使うか」「何に注意するか」「何を問うか」で引けるように整理しました。

How to use

AIに実装を頼む前の6ステップ

  1. 01目的と制約を書く
  2. 02一番単純な構成を選ぶ
  3. 03境界と正本を決める
  4. 04失敗時の戻し方を決める
  5. 05小さく実装して検証する
  6. 06判断理由を残す

迷ったときの基本姿勢

最初は単純に。 モノリス、RDB、同期API、少ない依存で始め、痛みが観測された場所だけ強くする。

境界は変化で切る。 一緒に変わるものを近くに置き、所有者やリリース責任が違うところに契約を置く。

生成速度より検証密度。 AIで速く書くほど、テスト、ブラウザ確認、ログ、ADRで現実に戻す。

Concept family

1. 判断レンズ

技術名を選ぶ前に、変更しやすさ、失敗範囲、制約、時間軸を見るための軸。

可逆性

Two-way door

後から戻せる判断か、戻すコストが高い判断かを分ける。

使う
小さく試せる UI、ライブラリ、内部実装は可逆として速く決める。
注意
DB 分割、公開 API、認証方式、データ削除方針は不可逆寄り。
問う
失敗したとき、1日で戻せるか。

爆発半径

Blast radius

失敗したときに影響を受けるユーザー、機能、データの範囲。

使う
危険な変更は feature flag、段階リリース、権限分離で狭める。
注意
共有 DB、共通ライブラリ、グローバル状態は影響範囲が広い。
問う
この変更が壊れたら、どこまで止まるか。

凝集度と結合度

Cohesion / coupling

一緒に変わるものは近く、別理由で変わるものは離す。

使う
モジュール境界、コンポーネント境界、サービス境界を決める。
注意
共通化しすぎると、関係ない変更まで巻き込まれる。
問う
これは同じ理由で変更される塊か。

複雑性予算

Complexity budget

チームが理解、運用、修正できる複雑さには上限がある。

使う
新しい技術や分散構成を入れる前に、削れる複雑さを探す。
注意
便利な抽象、生成コード、ツール連携は見えない学習コストを増やす。
問う
この複雑さは、何を明確に買っているか。

変更頻度

Volatility

よく変わる部分と安定している部分を別々に扱う。

使う
価格計算、権限、UI 文言、外部 API 接続など変わりやすい領域を隔離する。
注意
初期に早すぎる抽象化をすると、実際の変化とズレる。
問う
ここは今後どのくらいの頻度で変わるか。

制約優先

Constraint first

理想設計より先に、期限、人員、法務、予算、既存資産を見る。

使う
採用技術や運用方式を現実の制約に合わせる。
注意
制約を無視した正しさは、完成しない設計になりやすい。
問う
絶対に動かせない制約は何か。

現在価値と将来価値

Now vs later

今の速度と将来の拡張性を交換していると自覚する。

使う
MVP は単純に作り、成長した部分だけ段階的に固くする。
注意
将来のためだけの設計は、未来が外れた瞬間に負債になる。
問う
これは今日の価値を増やすか、将来の選択肢を増やすか。

所有境界

Ownership boundary

誰が直し、誰が運用し、誰が仕様を決めるかで境界を引く。

使う
チーム、ドメイン、リリース責任が違うところに明確な契約を置く。
注意
所有者不明の共通基盤は、誰も直せない重要部品になる。
問う
壊れたとき、誰が最初に見るか。

Concept family

2. コード設計

単一ファイルの実装から大きなコードベースまで効く、読みやすさと変更容易性の土台。

抽象化

Abstraction

細部を隠し、使う側に必要な意味だけを見せる。

使う
呼び出し元が実装詳細に依存し始めたら導入する。
注意
早すぎる抽象化は、実際の違いを隠して変更を難しくする。
問う
隠すべき詳細と、見せるべき契約は何か。

カプセル化

Encapsulation

状態とルールを近くに置き、外から壊せないようにする。

使う
不正な状態を作れてしまうデータ構造に使う。
注意
ただ private にするだけでは、責務の分離にはならない。
問う
この状態を正しく変えられる入口はどこか。

関心の分離

Separation of concerns

表示、データ取得、権限、永続化など異なる関心を混ぜない。

使う
1つの関数やコンポーネントが複数理由で変わるとき。
注意
分けすぎると、読むために多くのファイルを往復する。
問う
このコードは何のために存在しているか。

依存性逆転

Dependency inversion

上位のルールを、具体的な DB や外部 API から切り離す。

使う
テスト、差し替え、外部サービス障害への耐性が必要な境界に使う。
注意
小さなアプリでは interface だらけになり、読みにくくなる。
問う
ここは具体実装に依存すべきか、契約に依存すべきか。

合成優先

Composition over inheritance

継承階層より、小さな部品を組み合わせて振る舞いを作る。

使う
状態、権限、表示差分などバリエーションが増える領域。
注意
部品が細かすぎると、全体像が追いにくい。
問う
これは親子関係か、組み合わせか。

不変条件

Invariant

システムが常に守るべきルールを明文化する。

使う
残高は負にならない、公開記事にはタイトルが必須、などの核になる制約。
注意
UI だけで守ると、API やバッチから壊れる。
問う
どの瞬間にも絶対に破れてはいけないルールは何か。

型安全

Type safety

間違った値の組み合わせを実行前に減らす。

使う
API レスポンス、状態遷移、権限、設定値など境界に使う。
注意
型が実行時データを保証するとは限らない。入力検証は別に必要。
問う
このバグは型で表現すれば消せるか。

副作用の隔離

Side-effect boundary

I/O、時間、乱数、外部 API など再現しにくい処理を端へ寄せる。

使う
テストしやすい純粋関数と、薄い副作用層に分ける。
注意
すべてを純粋にしようとすると、アプリの目的から遠ざかる。
問う
この処理は同じ入力で同じ結果になるか。

Concept family

3. デザインパターン

名前を知っていると会話が速くなる、実装上のよくある形。ただし万能薬ではない。

Singleton

アプリ全体でインスタンスを1つだけ持つ。

使う
設定、ロガー、接続プールのように共有が自然なもの。
注意
グローバル状態になり、テストや並列実行を難しくしやすい。
問う
本当に1つである必要があるか。

Factory

生成ロジックを呼び出し側から隠す。

使う
環境、設定、入力タイプで作るオブジェクトが変わるとき。
注意
単純な new の置き換えだけなら過剰。
問う
生成条件は今後増えるか。

Strategy

アルゴリズムや方針を差し替え可能にする。

使う
料金計算、ソート、認証、通知などルールが複数あるとき。
注意
分岐が2つだけで安定しているなら関数分岐で十分なこともある。
問う
この条件分岐は方針として名前を持つか。

Adapter

外部や旧実装のインターフェースを、自分たちの形に変換する。

使う
SaaS、決済、CMS、レガシー API を内側へ直接入れたくないとき。
注意
外部仕様を漏らす Adapter は防波堤にならない。
問う
外部 API を変えても内側のコードは残るか。

Facade

複雑な内部手続きを、単純な入口にまとめる。

使う
複数ステップの保存、通知、課金、分析送信などを1つの操作に見せる。
注意
Facade が巨大化すると、ただの神クラスになる。
問う
呼び出し元が知る必要のない順序は何か。

Observer

Pub/Sub

ある出来事を、関心のある購読者へ通知する。

使う
UI イベント、ドメインイベント、通知、分析ログなど。
注意
誰が何を起こしたか追いにくく、デバッグが難しくなる。
問う
直接呼び出すより、イベントとして広げる価値はあるか。

Command

操作をオブジェクトやデータとして表現する。

使う
Undo/Redo、キュー投入、監査ログ、再実行が必要な操作。
注意
単純なボタンクリックまで Command にすると遠回り。
問う
この操作は保存、再試行、取り消しされるか。

State Machine

状態と遷移を明示し、不正な遷移を防ぐ。

使う
注文、認証、ワークフロー、ゲーム、アップロードなど段階がある処理。
注意
状態が少ないうちは enum と関数で十分な場合もある。
問う
次に行ける状態は明確に列挙できるか。

Concept family

4. アーキテクチャスタイル

アプリ全体の分け方。チーム、デプロイ、データ、責任境界の設計に効く。

Monolith

1つのアプリとして開発、ビルド、デプロイする。

使う
初期プロダクト、少人数、ドメインがまだ固まっていない段階。
注意
境界を作らないと、成長後に変更影響が読みにくくなる。
問う
まず1つで速く学ぶ方が価値が高いか。

Modular Monolith

デプロイは1つ、内部は明確なモジュールに分ける。

使う
マイクロサービスほど運用を増やさず、境界は育てたいとき。
注意
モジュール間で DB や内部型を自由に触ると崩れる。
問う
サービス分割前に、コード境界だけで解けないか。

Layered Architecture

UI、アプリケーション、ドメイン、インフラなど層で分ける。

使う
標準的な業務アプリ、CRUD、多人数で読みやすさを優先するとき。
注意
層をまたぐだけの薄いファイルが増えすぎることがある。
問う
依存方向は上から下へ保てているか。

Clean / Hexagonal

ドメインを中心に置き、外部 I/O をポートとアダプターに分ける。

使う
業務ルールが長く残り、DB や外部 API を差し替える可能性があるとき。
注意
小規模な画面中心アプリでは構造が重くなりやすい。
問う
守りたい中心ルールは何か。

Microservices

独立デプロイできる小さなサービス群で構成する。

使う
チーム自律性、スケール特性、障害分離が本当に必要なとき。
注意
分散トランザクション、監視、認証、通信障害のコストが増える。
問う
コード分割ではなく、デプロイ分割が必要か。

Event-Driven Architecture

出来事をイベントとして発行し、購読側が非同期に反応する。

使う
通知、連携、監査、集計など発生元と処理先を疎結合にしたいとき。
注意
結果整合性、重複配信、順序、再処理を設計する必要がある。
問う
即時応答より、疎結合と拡張性が重要か。

Serverless

サーバー管理をクラウド側へ寄せ、関数やマネージドサービスで構成する。

使う
負荷が読みにくい、運用人数が少ない、イベント駆動の処理。
注意
cold start、実行時間制限、ローカル再現性、ベンダーロックイン。
問う
運用を減らす価値が、制約を上回るか。

BFF

Backend for Frontend

フロントエンド体験に合わせた薄いバックエンドを置く。

使う
Web、モバイル、管理画面で必要な API 形状が違うとき。
注意
BFF に業務ロジックを溜めると、重複と分散が起きる。
問う
これは画面都合の整形か、ドメインルールか。

Concept family

5. データと整合性

保存、検索、集計、変更履歴をどう扱うか。多くの設計事故はここで起きる。

RDBMS

表、制約、SQL、トランザクションで構造化データを扱う。

使う
整合性、集計、関係、検索条件が重要な一般的なアプリ。
注意
スキーマ変更と巨大テーブルの migration は計画が必要。
問う
関係と整合性を DB に守らせたいか。

NoSQL

ドキュメント、キー値、グラフなど用途別の形でデータを持つ。

使う
アクセスパターンが明確、スキーマ柔軟性や水平スケールが重要なとき。
注意
柔軟さは、アプリ側の整合性責任を増やす。
問う
読み書きパターンは十分に固定されているか。

ACID Transaction

複数変更を、全部成功か全部失敗として扱う。

使う
決済、在庫、権限、台帳など不整合が許されない処理。
注意
長い transaction はロックと性能問題を起こす。
問う
途中成功が見えてはいけない処理か。

正規化

Normalization

重複を減らし、更新不整合を避けるデータ設計。

使う
同じ事実を複数箇所で更新したくないとき。
注意
読み取りが複雑になり、JOIN や API 結合が増えることがある。
問う
この値の正本はどこか。

非正規化

Denormalization

読み取りや表示のために、あえてデータを重複させる。

使う
一覧、検索、分析、キャッシュ、履歴スナップショット。
注意
更新タイミングと再計算ルールを明確にしないとズレる。
問う
重複した値は、いつ誰が更新するか。

Index

検索を速くするための補助データ構造。

使う
WHERE、ORDER BY、JOIN、ユニーク制約で頻繁に使う列。
注意
書き込みは遅くなり、不要 index はストレージと保守を増やす。
問う
実際のクエリ計画で使われているか。

Migration

スキーマやデータを段階的に安全に変える作業。

使う
カラム追加、型変更、バックフィル、テーブル分割。
注意
コードと DB の互換期間を考えないとデプロイ中に落ちる。
問う
古いコードと新しい DB は同時に動けるか。

CQRS

書き込みモデルと読み取りモデルを分ける。

使う
複雑な検索、集計、表示最適化と、厳密な更新ルールを両立したいとき。
注意
同期、遅延、二重モデルの保守コストが増える。
問う
読み取り都合が書き込みモデルを歪めていないか。

Concept family

6. APIと分散連携

境界を越える通信は必ず失敗する前提で、契約、再試行、順序、重複を設計する。

REST

リソースを URL と HTTP メソッドで扱う API スタイル。

使う
公開 API、CRUD、キャッシュ、標準ツールとの相性を重視するとき。
注意
複雑な画面要求では overfetch / underfetch が起きる。
問う
これはリソースとして自然に表せるか。

GraphQL

クライアントが必要な形のデータを問い合わせる。

使う
複数クライアント、複雑な画面、API 集約が必要なとき。
注意
認可、N+1、キャッシュ、クエリ複雑度制限が必要。
問う
クライアントごとのデータ形状差が大きいか。

RPC

関数呼び出しのように、明確な操作を API として公開する。

使う
内部サービス間、型共有、低遅延、手続き的操作が中心のとき。
注意
ネットワーク越しなのにローカル関数の感覚で扱うと危険。
問う
リソースより操作として考える方が自然か。

Queue

処理を一度キューへ入れ、ワーカーが後で実行する。

使う
メール送信、画像処理、外部 API 連携、重い処理の非同期化。
注意
重複実行、失敗再試行、順序、遅延を考える必要がある。
問う
ユーザー応答から切り離せる処理か。

Pub/Sub

発行者が購読者を知らずにイベントを広げる。

使う
複数システムが同じ出来事に反応する連携。
注意
購読者が増えるほど、全体の因果関係が見えにくくなる。
問う
処理先を発行元から独立させたいか。

Timeout / Retry

外部呼び出しは必ず時間切れと再試行方針を持つ。

使う
HTTP、DB、キュー、SaaS 連携など全ての外部境界。
注意
無制限 retry は障害を増幅する。backoff と上限が必要。
問う
失敗時に、何秒待って何回やり直すか。

Circuit Breaker

失敗が続く外部依存を一時的に遮断する。

使う
下流障害が上流全体を巻き込むのを防ぐ。
注意
開閉条件とフォールバック体験を決めないと使えない。
問う
下流が落ちたとき、こちらはどう縮退するか。

Outbox / Saga

複数システムにまたがる更新を、イベント記録や補償処理で管理する。

使う
注文、決済、在庫、通知など分散した一連の業務処理。
注意
完全な一発成功を期待せず、補償と再処理を設計する。
問う
途中失敗したとき、どう戻すか進めるか。

Concept family

7. フロントエンドとUX

画面の作り方は、表示速度、状態、アクセシビリティ、保守性を同時に決める。

SSR / SSG / CSR

HTML をどこで作るか。サーバー、ビルド時、ブラウザで役割が変わる。

使う
SEO、初期表示、更新頻度、認証状態に合わせて選ぶ。
注意
全部 CSR にすると初期表示が遅く、全部 SSR にすると運用が重いことがある。
問う
この画面の最初の HTML はどこで作るべきか。

Hydration / Islands

静的 HTML の一部だけをインタラクティブにする。

使う
記事、ポートフォリオ、ドキュメントに小さな操作部品を混ぜるとき。
注意
水和範囲が広いほど JS と状態同期のコストが増える。
問う
この部分は本当にクライアント JS が必要か。

Component Boundary

UI を責務のある部品に分ける。

使う
再利用、テスト、デザインシステム、状態管理を整理する。
注意
見た目だけで分けると、データや責務が散らばる。
問う
この部品は何を知り、何を知らないべきか。

State Management

画面状態、サーバー状態、URL 状態、フォーム状態を分けて扱う。

使う
状態の所有者と寿命を明確にする。
注意
全部をグローバル store に入れると依存が読めなくなる。
問う
この状態の正本は URL、サーバー、親、ローカルのどれか。

Design System

UI 部品、トークン、振る舞い、アクセシビリティを共通化する。

使う
画面数やチームが増え、体験の一貫性が必要なとき。
注意
現場の実装速度を落とすだけの規則集にしない。
問う
共通化すると、利用側の判断が減るか。

Accessibility

a11y

キーボード、スクリーンリーダー、色覚、認知負荷を含めて使えるようにする。

使う
すべての UI。後付けより最初から設計する方が安い。
注意
aria を足す前に、まず semantic HTML を使う。
問う
マウスなし、色なし、音声読み上げでも使えるか。

Optimistic UI

サーバー成功を待たず、先に成功したように UI を更新する。

使う
いいね、並び替え、軽い編集など失敗率が低い操作。
注意
失敗時の戻し方、二重送信、競合を設計する。
問う
失敗したとき、自然に戻せる操作か。

Progressive Enhancement

基本機能を堅く作り、環境が良いほど体験を強化する。

使う
フォーム、記事、検索、公共性の高いページ。
注意
高度な JS 体験だけに依存すると、壊れたときに何も残らない。
問う
JS が失敗しても最低限の価値は残るか。

Concept family

8. 品質と保守性

正しく動くことを、人間の記憶ではなく仕組みで支えるための概念。

Testing Pyramid

単体テストを厚く、統合と E2E を要所に置く考え方。

使う
速度、信頼性、保守コストのバランスを取る。
注意
ピラミッド形にこだわりすぎず、リスクに合わせる。
問う
この失敗はどの粒度のテストで最も安く捕まるか。

Unit Test

小さな関数やモジュールを高速に検証する。

使う
計算、変換、バリデーション、状態遷移など純粋なロジック。
注意
実装詳細に密着しすぎると、リファクタで壊れやすい。
問う
入力と出力だけで重要な性質を確認できるか。

Integration Test

複数部品が接続された状態を検証する。

使う
DB、API、認証、外部 adapter との境界。
注意
環境準備が重いと、実行されないテストになる。
問う
部品単体では見えない接続リスクは何か。

Contract Test

サービスや API の約束が破れていないか検証する。

使う
フロントとバック、サービス間、外部公開 API。
注意
実データの例だけでは、境界条件が抜ける。
問う
利用側が依存している約束は明文化されているか。

E2E Test

ユーザーに近い流れをブラウザや実環境で検証する。

使う
ログイン、購入、投稿、管理操作など壊れると痛い主要導線。
注意
遅く不安定になりやすいので、数を絞って価値の高い流れに使う。
問う
この導線が壊れたら事業や信頼に響くか。

Static Analysis

型、lint、format、依存チェックで実行前に問題を捕まえる。

使う
人間レビューで見落としやすい機械的品質を守る。
注意
ルールが多すぎると、回避や無視が増える。
問う
人間が見るべきでないミスを機械に渡せているか。

Feature Flag

コードを入れたまま、機能の公開範囲を制御する。

使う
段階リリース、A/B テスト、緊急停止、権限別提供。
注意
古い flag を消さないと条件分岐の迷路になる。
問う
リリースと公開を分ける必要があるか。

Technical Debt

将来の変更コストを増やす設計上の借り。

使う
意図して借り、返済条件と期限を記録するなら有効。
注意
借りた自覚がない負債は、見積もりを静かに壊す。
問う
これは急ぐための借りか、ただの見落としか。

Concept family

9. 運用とセキュリティ

作って終わりにしないための、デプロイ、監視、権限、事故対応の基礎。

CI/CD

テスト、ビルド、デプロイを自動化して小さく速く届ける。

使う
人間の手順ミスを減らし、変更単位を小さく保つ。
注意
壊れた pipeline は信頼されず、結局手作業に戻る。
問う
main に入る前後で何を必ず確認するか。

Environment

local、preview、staging、production など実行環境を分ける。

使う
本番前に設定、データ、権限、性能の差分を確認する。
注意
環境差が大きすぎると、検証の意味が薄くなる。
問う
本番だけで起きる差分は何か。

Secret Management

API key、token、証明書をコードやログに出さず管理する。

使う
環境変数、secret store、権限分離、rotation。
注意
サンプル、スクリーンショット、生成コードの中に混ざりやすい。
問う
この値は公開リポジトリに出ても安全か。

Observability

未知の障害を、ログ、メトリクス、トレースから調べられる状態。

使う
本番でしか起きない遅延、失敗、データ不整合を追う。
注意
ログ量だけ多くても、相関 ID や意味がなければ追えない。
問う
ユーザーの1リクエストを最後まで追えるか。

SLO / SLI

信頼性を、測れる指標と守る目標にする。

使う
可用性、遅延、エラー率、処理成功率を運用判断に使う。
注意
100% を目標にすると、速度も投資判断も硬直する。
問う
ユーザーにとって許せない失敗率はどこか。

Authentication / Authorization

誰かを確認することと、何を許すかを分ける。

使う
ログイン、組織、ロール、リソース単位のアクセス制御。
注意
UI で隠すだけでは認可にならない。API と DB でも守る。
問う
このユーザーは、この対象に、この操作をしてよいか。

Least Privilege

必要最小限の権限だけを与える。

使う
DB ユーザー、CI token、クラウド権限、管理画面。
注意
一時的な管理者権限が放置されがち。
問う
この権限が漏れたら何ができてしまうか。

Incident Response

障害時に、検知、切り分け、復旧、振り返りを行う流れ。

使う
サービスが本番利用されるなら、規模に応じた手順を用意する。
注意
犯人探しではなく、再発防止と検知改善に集中する。
問う
今落ちたら、誰が何を見て何を止めるか。

Concept family

10. AI時代の実装作法

生成速度が上がるほど、仕様、境界、検証、レビューの設計が重要になる。

Spec-first

先に目的、制約、完成条件を短く書く。

使う
AI に実装させる前に、何を変え何を変えないか固定する。
注意
曖昧な依頼は、動くが目的とズレたコードを生む。
問う
成功条件をテストや画面で確認できる形に書いたか。

Small Slice

大きな変更を、検証可能な小さい単位に切る。

使う
生成コードの diff を読み切れるサイズに保つ。
注意
一度に UI、DB、認証、デプロイを変えると失敗原因が見えない。
問う
この変更は1レビューで理解できるか。

Context Packing

AI に必要なファイル、制約、既存パターンを先に渡す。

使う
リポジトリ固有の設計や命名を守りたいとき。
注意
情報を詰めすぎると、重要な制約が埋もれる。
問う
この実装判断に必要な文脈は何か。

Guardrail

禁止事項、編集範囲、セキュリティ制約を明示する。

使う
機密、破壊的操作、課金、認証、データ削除に触れる作業。
注意
口頭の注意だけでなく、テストや CI に落とし込む。
問う
AI がやってはいけないことは明確か。

Generated Code Review

生成されたコードを、人間が設計意図とリスクで読む。

使う
AI が書いた diff を、そのまま正解扱いしない。
注意
それっぽい抽象化、未使用コード、境界漏れ、秘密情報混入を探す。
問う
このコードを半年後の自分が直せるか。

Verification Loop

実装、テスト、ブラウザ確認、ログ確認を短く回す。

使う
AI で速く書くほど、実行結果で早く現実に戻す。
注意
ビルド成功だけでは、UX や権限や本番差分は確認できない。
問う
この変更の一番大事な失敗は、どう検出するか。

ADR

Architecture Decision Record

重要な設計判断の背景、選択肢、理由を短く残す。

使う
不可逆、広範囲、高コストな判断をしたとき。
注意
長すぎる文書は読まれない。判断単位で軽く残す。
問う
未来の人は、なぜこれを選んだか分かるか。

Public-safe Output

公開物には、秘密、内部事情、個人情報を混ぜない。

使う
ブログ、ドキュメント、スクリーンショット、生成物の公開前確認。
注意
ログ、URL、環境変数、顧客名、メール、トークン断片に注意する。
問う
このページを誰が見ても問題ないか。