LESSON 30分

ストーリー

佐藤CTO
さて、アーキテクチャの重要性はわかったね。じゃあ早速、どのアーキテクチャパターンを採用するか決めよう…と言いたいところだけど

佐藤CTOが立ち止まりました。

あなた
え?パターンの選定ではないんですか?
佐藤CTO
まだ早い。まずビジネスを理解しないとアーキテクチャは選べない。多くのエンジニアが犯す過ちは、技術的な観点だけでアーキテクチャを決めてしまうことだ
あなた
ビジネスの理解…ですか
佐藤CTO
そう。誰がこのシステムを使うのか、何を実現したいのか、どんな制約があるのか。それを正確に把握しなければ、どんなに優れたアーキテクチャも的外れになる

ステークホルダー分析

ステークホルダーとは

アーキテクチャに影響を与える、または影響を受けるすべての関係者です。

// ステークホルダーの分類
interface StakeholderMap {
  // 直接的なステークホルダー
  direct: {
    endUsers: "エンドユーザー -- システムを実際に使う人";
    productOwner: "プロダクトオーナー -- ビジネス価値を定義する人";
    developers: "開発チーム -- システムを構築・保守する人";
    operators: "運用チーム -- システムを監視・管理する人";
  };
  // 間接的なステークホルダー
  indirect: {
    management: "経営層 -- 予算・リソースの意思決定者";
    security: "セキュリティチーム -- セキュリティ要件を定義する人";
    compliance: "法務・コンプライアンス -- 規制要件を管理する人";
    partners: "外部パートナー -- API連携先、サードパーティサービス";
  };
}

ステークホルダーごとの関心事

各ステークホルダーはそれぞれ異なる関心事(Concern)を持っています。

ステークホルダー主な関心事アーキテクチャへの影響
エンドユーザーレスポンス速度、使いやすさパフォーマンス要件、UX設計
プロダクトオーナー機能追加の速度、市場投入時間モジュール性、デプロイ頻度
開発チーム開発しやすさ、テスト容易性コード構造、CI/CDパイプライン
運用チーム監視しやすさ、障害対応の容易さ可観測性、障害分離
経営層コスト、ROI、リスクインフラコスト、スケーリング戦略
セキュリティデータ保護、アクセス制御認証認可アーキテクチャ、暗号化
// ステークホルダー分析テンプレート
interface StakeholderAnalysis {
  stakeholder: string;
  role: string;
  concerns: string[];
  influence: "高" | "中" | "低";  // アーキテクチャへの影響度
  priority: "高" | "中" | "低";   // 対応の優先度
}

// ECサイトの例
const stakeholderAnalysis: StakeholderAnalysis[] = [
  {
    stakeholder: "購入者(エンドユーザー)",
    role: "商品を検索・購入する",
    concerns: ["検索が速いこと", "決済が安全なこと", "在庫がリアルタイムに見えること"],
    influence: "高",
    priority: "高",
  },
  {
    stakeholder: "出品者(ビジネスユーザー)",
    role: "商品を登録・管理する",
    concerns: ["商品登録が簡単なこと", "売上データが正確なこと"],
    influence: "中",
    priority: "高",
  },
  {
    stakeholder: "経営層",
    role: "プラットフォームの収益を最大化する",
    concerns: ["インフラコスト", "スケール時のコスト増加率", "障害による売上損失"],
    influence: "高",
    priority: "中",
  },
];

ユースケースモデリング

ユースケースからアーキテクチャ要件を抽出する

ユースケースは機能要件を整理するだけでなく、アーキテクチャに影響する非機能的な特性を発見するためにも使います。

// アーキテクチャ視点のユースケース記述
interface ArchitecturalUseCase {
  name: string;
  actor: string;
  description: string;
  // ここからがL3で追加する視点
  frequency: string;          // どのくらいの頻度で実行されるか
  dataVolume: string;         // どのくらいのデータを扱うか
  latencyRequirement: string; // どのくらい速くないといけないか
  concurrency: string;        // 同時にどのくらい実行されるか
  consistency: string;        // どこまでの一貫性が必要か
}

// ECサイトの「商品を検索する」ユースケース
const searchProductUseCase: ArchitecturalUseCase = {
  name: "商品を検索する",
  actor: "購入者",
  description: "キーワードや条件を指定して商品を検索し、結果一覧を表示する",
  frequency: "ピーク時に10,000リクエスト/秒",
  dataVolume: "検索対象: 500万商品、結果: 20件/ページ",
  latencyRequirement: "p99 < 200ms",
  concurrency: "ピーク時に50,000同時ユーザー",
  consistency: "多少の遅延(数秒)は許容(結果整合性でOK)",
};

// ECサイトの「注文を確定する」ユースケース
const placeOrderUseCase: ArchitecturalUseCase = {
  name: "注文を確定する",
  actor: "購入者",
  description: "カート内の商品の在庫を確認し、決済を実行し、注文を確定する",
  frequency: "ピーク時に500リクエスト/秒",
  dataVolume: "注文データ: 平均3商品/注文",
  latencyRequirement: "p99 < 2000ms(決済処理含む)",
  concurrency: "ピーク時に5,000同時処理",
  consistency: "強い一貫性が必須(二重注文・在庫不整合は許容不可)",
};

「同じシステムでも、ユースケースによって求められる品質特性がまったく違う。検索は”速さ”が命で多少の古いデータは許せるが、注文確定は”正確さ”が命で遅延は許せる。この違いがアーキテクチャ設計を左右する」 — 佐藤CTO


DDDの戦略的パターンによるドメイン分析

境界づけられたコンテキスト(Bounded Context)

L2でヘキサゴナルアーキテクチャを学んだとき、「ドメイン」という概念に触れました。L3では、複数のドメインをどう分割・連携するかを考えます。

// ECサイトの境界づけられたコンテキスト
namespace BoundedContexts {
  // カタログコンテキスト:商品情報の管理
  namespace Catalog {
    interface Product {
      productId: string;
      name: string;
      description: string;
      price: Money;
      category: Category;
      // ここでの「Product」は商品マスタ情報
    }
  }

  // 注文コンテキスト:注文の管理
  namespace Ordering {
    interface Product {
      productId: string;
      name: string;
      unitPrice: Money;
      // ここでの「Product」は注文時点のスナップショット
      // 詳細な説明やカテゴリは不要
    }

    interface Order {
      orderId: string;
      items: OrderItem[];
      totalAmount: Money;
      status: OrderStatus;
    }
  }

  // 在庫コンテキスト:在庫の管理
  namespace Inventory {
    interface Product {
      productId: string;
      sku: string;
      stockQuantity: number;
      warehouseLocation: string;
      // ここでの「Product」は在庫管理の対象
      // 価格や説明は不要
    }
  }
}
// 同じ「Product」でもコンテキストによって意味が異なる!

コンテキストマップ

境界づけられたコンテキスト間の関係を可視化するのがコンテキストマップです。

graph TD
    A["カタログ<br/>コンテキスト"] -->|"U/D"| B["検索<br/>コンテキスト"]
    A -->|"Published Language"| C["注文<br/>コンテキスト"]
    C -->|"ACL"| D["決済<br/>コンテキスト"]
    C -->|"Domain Event"| E["在庫<br/>コンテキスト"]
    E -->|"OHS"| F["配送<br/>コンテキスト"]

    classDef ctxStyle fill:#4a90d9,stroke:#2c5f8a,color:#fff
    class A,B,C,D,E,F ctxStyle
  • U/D = Upstream/Downstream
  • ACL = Anti-Corruption Layer(腐敗防止層)
  • OHS = Open Host Service(公開ホストサービス)

コンテキスト間の関係パターン

パターン説明使いどころ
共有カーネル(Shared Kernel)共通のドメインモデルを共有密接に連携する2チーム
顧客/供給者(Customer/Supplier)上流が下流の要件を尊重同組織内のチーム間
適合者(Conformist)下流が上流のモデルに従う外部サービスへの依存
腐敗防止層(ACL)変換層で外部モデルを隔離外部APIとの連携
公開ホストサービス(OHS)標準化されたAPIを提供複数の消費者がいるサービス
公表された言語(PL)共通のデータ形式を定義組織横断のデータ交換

ビジネスキャパビリティマッピング

ビジネスキャパビリティとは

組織が持つ「何ができるか」という能力の分類です。ドメインの分割やサービス境界の決定に使います。

// ECプラットフォームのビジネスキャパビリティマップ
interface BusinessCapabilityMap {
  顧客管理: {
    アカウント管理: "ユーザー登録、認証、プロフィール管理";
    ロイヤルティ管理: "ポイント、会員ランク、クーポン";
    顧客サポート: "問い合わせ対応、返品対応";
  };
  商品管理: {
    カタログ管理: "商品登録、カテゴリ管理、画像管理";
    価格管理: "価格設定、割引、セール管理";
    レビュー管理: "レビュー投稿、評価、モデレーション";
  };
  受注管理: {
    カート管理: "カート追加、数量変更、保存";
    注文処理: "注文確定、注文変更、キャンセル";
    決済処理: "クレジットカード、電子マネー、後払い";
  };
  フルフィルメント: {
    在庫管理: "入出庫、在庫照会、発注点管理";
    配送管理: "配送手配、追跡、配達完了";
    返品管理: "返品受付、検品、返金処理";
  };
}

「ビジネスキャパビリティは、技術的な関心事ではなくビジネスの関心事で分割する。これがサービス境界を決める最も安定した基準になる。なぜなら、技術は変わってもビジネスの本質的な構造はそう簡単には変わらないからだ」 — 佐藤CTO


ビジネス要件から技術要件への変換

分析したビジネス要件を、アーキテクチャに影響する技術要件に変換するプロセスです。

// ビジネス要件 → 技術要件の変換例
interface RequirementTranslation {
  businessRequirement: string;
  technicalImplication: string;
  architecturalImpact: string;
}

const translations: RequirementTranslation[] = [
  {
    businessRequirement: "セール時に通常の10倍のアクセスが来る",
    technicalImplication: "ピーク時100,000 QPS に耐えるスケーラビリティ",
    architecturalImpact: "水平スケーリング、CDN、キャッシュ戦略、オートスケーリング",
  },
  {
    businessRequirement: "注文データは絶対に失えない",
    technicalImplication: "99.999%のデータ耐久性、RPO=0",
    architecturalImpact: "マルチAZレプリケーション、WAL、定期バックアップ",
  },
  {
    businessRequirement: "新機能を毎週リリースしたい",
    technicalImplication: "週1回以上のデプロイ頻度、ゼロダウンタイム",
    architecturalImpact: "CI/CDパイプライン、Blue-Greenデプロイ、フィーチャーフラグ",
  },
  {
    businessRequirement: "個人情報保護法に準拠する必要がある",
    technicalImplication: "データの暗号化、アクセス制御、監査ログ",
    architecturalImpact: "暗号化at-rest/in-transit、RBAC、監査証跡サービス",
  },
  {
    businessRequirement: "海外展開を2年以内に予定している",
    technicalImplication: "マルチリージョン対応、i18n/l10n",
    architecturalImpact: "マルチリージョンデプロイ、データレジデンシー、CDN",
  },
];

変換の4ステップ

ステップ活動アウトプット
1. ステークホルダー分析誰が何を求めているかを整理ステークホルダーマップ
2. ユースケース分析主要なユースケースの品質特性を抽出アーキテクチャ視点のユースケース
3. ドメイン分析境界づけられたコンテキストを特定コンテキストマップ
4. 要件変換ビジネス要件を技術要件に翻訳技術要件リスト

まとめ

ポイント内容
ステークホルダー分析誰がどんな関心事を持つかを整理する
ユースケースモデリング機能要件に品質特性(頻度、遅延、一貫性)を加える
ドメイン分析DDDの戦略的パターンで境界を特定する
ビジネスキャパビリティビジネスの能力でサービス境界を決める
要件変換ビジネス要件を技術要件に翻訳する

チェックリスト

  • ステークホルダー分析の目的と手法を理解した
  • ユースケースからアーキテクチャ要件を抽出する方法を把握した
  • 境界づけられたコンテキストの概念を説明できる
  • コンテキストマップの主要パターンを理解した
  • ビジネス要件から技術要件への変換プロセスを把握した

次のステップへ

ビジネス要件の分析手法を学んだところで、次は「品質属性シナリオ」を学びます。「速い」「安全」「落ちない」という曖昧な要件を、測定可能な品質属性として定義する技術を身につけましょう。


推定読了時間: 30分