LESSON 15分

ストーリー

佐藤CTO
ここまでで、ビジネス要件の分析と品質属性の定量化を学んだね。さて、最後のピースだ
佐藤CTO
要件」→「?」→「アーキテクチャ
佐藤CTO
この”?”の部分を埋めるのが今日の学びだ。要件をアーキテクチャに変換するプロセス。ここが最もアーキテクトの腕の見せどころであり、最も経験が必要な部分でもある
あなた
具体的にはどうするんですか?
佐藤CTO
アーキテクチャドライバーを特定し、各品質属性に対応する戦術(Tactics)を選び、それらを組み合わせて全体のアーキテクチャを構成する。ちょうどレゴブロックを組み上げるようにね

アーキテクチャドライバー

アーキテクチャドライバーとは

アーキテクチャの構造を決定づける、最も影響の大きい要件のことです。すべての要件がアーキテクチャに影響するわけではありません。

// アーキテクチャドライバーの分類
interface ArchitecturalDrivers {
  // 主要な機能要件(アーキテクチャに影響するもの)
  keyFunctionalRequirements: string[];
  // 品質属性シナリオ(優先度「必須」「重要」のもの)
  qualityAttributeScenarios: string[];
  // 制約(変更不可能な条件)
  constraints: string[];
}

// ECサイトのアーキテクチャドライバー例
const ecSiteDrivers: ArchitecturalDrivers = {
  keyFunctionalRequirements: [
    "リアルタイム在庫管理(複数倉庫からの在庫集約)",
    "複数決済手段の統合(クレジット、電子マネー、後払い)",
    "全文検索(500万商品、ファセット検索、パーソナライズ)",
  ],
  qualityAttributeScenarios: [
    "QA-001: 注文処理の可用性 99.99%",
    "QA-002: 検索API p99 < 200ms",
    "QA-003: セール時10倍トラフィックへの自動スケーリング",
    "QA-004: 個人情報・決済情報の暗号化",
  ],
  constraints: [
    "AWS上で構築(社内規定)",
    "既存の会員管理システム(Java/Oracle)と連携が必要",
    "PCI DSS準拠(クレジットカード情報の取り扱い)",
    "開発チーム12名(TypeScript/Go経験者)",
  ],
};

「制約は見落とされがちだが、アーキテクチャを最も強力に規定する。“チームが使える技術”、“既存システムとの連携”、“法規制” — これらはトレードオフですらなく、変更不可能な前提条件だ」 — 佐藤CTO


アーキテクチャ戦術(Tactics)

戦術とは

品質属性シナリオを実現するための設計上の判断の単位です。パターンよりも粒度が細かく、特定の品質属性を向上させるための具体的なテクニックです。

可用性の戦術

// 可用性を実現するための戦術カタログ
const availabilityTactics = {
  障害検知: {
    ヘルスチェック: "定期的にサービスの生存を確認する",
    ハートビート: "サービスが定期的に生存信号を送る",
    タイムアウト: "応答がない場合に障害と判定する",
  },
  障害回復: {
    冗長化: "同じ機能を複数のインスタンスで提供する",
    フェイルオーバー: "障害時に待機系に切り替える",
    リトライ: "一時的な障害に対して再試行する",
    サーキットブレーカー: "連鎖障害を防止する",
  },
  障害防止: {
    例外処理: "予期しないエラーを適切に処理する",
    ロールバック: "更新に失敗したときに前の状態に戻す",
    グレースフルデグラデーション: "一部機能を犠牲にしてコア機能を維持する",
  },
};

パフォーマンスの戦術

// パフォーマンスを実現するための戦術カタログ
const performanceTactics = {
  リソース需要の管理: {
    キャッシュ: "計算結果やデータを再利用可能な場所に保存する",
    データ圧縮: "転送データ量を削減する",
    レート制限: "過剰なリクエストを制御する",
  },
  リソース管理: {
    コネクションプール: "DB接続を再利用する",
    並行処理: "独立した処理を並列に実行する",
    非同期処理: "重い処理をバックグラウンドに委譲する",
  },
  リソース調停: {
    スケジューリング: "リソースの優先度を制御する",
    負荷分散: "リクエストを複数のインスタンスに分配する",
  },
};

戦術の組み合わせ

graph TD
    Title["品質属性シナリオ:
検索API p99 < 200ms"] A["キャッシュ
検索結果をRedisにキャッシュ"] B["非同期処理
検索インデックスの更新は非同期"] C["負荷分散
複数の検索ノードに分散"] D["データ配置
専用の検索エンジン(Elasticsearch)"] Title ~~~ A A -->|"キャッシュミス時"| B B --> C C --> D Note["複数の戦術を組み合わせて
品質属性を実現する"] D ~~~ Note classDef titleStyle fill:#1e293b,stroke:#475569,color:#f8fafc classDef tacticStyle fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e40af classDef noteStyle fill:#fef3c7,stroke:#d97706,stroke-width:2px,color:#92400e class Title titleStyle class A,B,C,D tacticStyle class Note noteStyle

要件からアーキテクチャパターンへのマッピング

マッピングテーブル

アーキテクチャドライバーの組み合わせから、適切なアーキテクチャパターンを選択します。

ドライバー推奨パターン理由
高い可用性 + 独立デプロイマイクロサービスサービス単位の障害分離
素早い開発 + 小チームモジュラーモノリス開発の単純さ + 将来の分割に備える
完全な監査証跡 + 状態の時系列管理イベントソーシングすべての状態変更を記録
読み書きの負荷特性が異なるCQRS読み取りと書き込みを独立にスケール
高スループットのデータ処理イベント駆動非同期 + 並列処理
段階的な既存システムの置き換えストラングラーフィグリスクを最小化した段階的移行
// マッピングの具体例:ECサイト
interface ArchitectureMapping {
  driver: string;
  selectedPattern: string;
  tactics: string[];
  rationale: string;
}

const ecSiteMappings: ArchitectureMapping[] = [
  {
    driver: "検索API p99 < 200ms + 500万商品",
    selectedPattern: "CQRS(読み取り最適化)",
    tactics: ["キャッシュ", "専用検索エンジン", "非同期インデックス更新"],
    rationale: "書き込み(商品登録)と読み取り(検索)の負荷特性が大きく異なる",
  },
  {
    driver: "注文処理の可用性99.99% + 決済の一貫性",
    selectedPattern: "Sagaパターン(分散トランザクション)",
    tactics: ["冗長化", "フェイルオーバー", "補償トランザクション"],
    rationale: "複数サービスにまたがる注文処理で、一貫性と可用性を両立",
  },
  {
    driver: "セール時10倍トラフィック",
    selectedPattern: "イベント駆動 + オートスケーリング",
    tactics: ["メッセージキュー", "水平スケーリング", "バックプレッシャー"],
    rationale: "非同期処理で負荷のピークを吸収し、必要に応じてスケールアウト",
  },
];

フィードバックループ

アーキテクチャ設計は一方通行ではありません。要件とアーキテクチャの間にはフィードバックループが存在します。

graph TD
    A["ビジネス要件"] --> B["品質属性シナリオ"]
    B --> C["アーキテクチャ<br/>ドライバー"]
    C --> D["戦術の選定 +<br/>パターン適用"]
    D --> E["アーキテクチャ<br/>候補の評価"]
    E -->|"フィードバック"| A
    E --> F["アーキテクチャ<br/>決定"]

    classDef reqStyle fill:#e8a838,stroke:#b07c1e,color:#fff
    classDef processStyle fill:#4a90d9,stroke:#2c5f8a,color:#fff
    classDef resultStyle fill:#5cb85c,stroke:#3d8b3d,color:#fff

    class A,B reqStyle
    class C,D,E processStyle
    class F resultStyle

フィードバックが発生するケース

ケース説明対応
実現不可能制約の中で品質属性を満たせないステークホルダーと要件を再交渉
コスト超過要件を満たすアーキテクチャのコストが予算を超える品質属性の優先度を再検討
新たな発見アーキテクチャ検討中に未知の制約が見つかる要件を追加・修正
トレードオフの顕在化品質属性間の競合が判明ステークホルダーと優先度を決定

「最初の設計が完璧であることはない。大事なのは、早い段階でフィードバックを回すことだ。コードを書き始めてから”この要件は実現不可能です”と言うのでは遅すぎる。アーキテクチャ設計の段階で気づけたかどうかで、プロジェクトの運命が分かれる」 — 佐藤CTO


まとめ

ポイント内容
アーキテクチャドライバーアーキテクチャを決定づける主要な要件と制約
戦術(Tactics)品質属性を実現するための具体的な設計テクニック
パターンマッピングドライバーの組み合わせから適切なパターンを選択
フィードバックループ要件とアーキテクチャは相互に影響し合う
制約の重要性チーム、既存システム、法規制は変更不可能な前提条件

チェックリスト

  • アーキテクチャドライバーの3分類(機能要件、品質属性、制約)を理解した
  • 可用性・パフォーマンスの主要な戦術を把握した
  • 戦術を組み合わせて品質属性を実現する方法を理解した
  • 要件からアーキテクチャパターンへのマッピングプロセスを把握した
  • フィードバックループの重要性を認識した

次のステップへ

Step 1で学んだ内容を理解度チェッククイズで確認しましょう。アーキテクチャの定義、ビジネス要件分析、品質属性シナリオ、戦術とパターンのマッピング — これらの基礎がしっかり身についているか試してみてください。


推定読了時間: 15分