Chuyển đến nội dung chính

レッスン 2: ドメイン駆動設計 — システム分離の考え方

DDD プラットフォーム: ユビキタス言語、境界コンテキスト、集約、ドメイン イベント。イベント ストーミングを使用してドメインを検出する方法。戦略的 DDD と戦術的 DDD およびマイクロサービスおよびマイクロ フロントエンド部門へのアプリケーション。

🏗️ アーキテクチャ — レッスン 2 レッスン 2: ドメイン駆動設計 — 分割された思考 システムの分離

マイクロサービスとマイクロ フロントエンドのシステム設計 — 基本から運用まで

パート 1: 基礎 — アーキテクチャの進化

xdev.asia

はじめに

ドメイン駆動設計 (DDD) は単なるコード記述方法ではなく、複雑なシステムをビジネスに意味のある部分に分解する考え方です。 DDD は、マイクロサービスをどのように分割するかとマイクロ フロントエンドをどのように分割するかを決定する基盤です。分割を誤ると、元のモノリスよりも悪い「分散モノリス」が作成されます。

コンテキスト マップ — DDD の境界付きコンテキストとドメイン間の関係


1. なぜ DDD が必要なのでしょうか?

1.1 技術的分解の問題

システムを 技術レイヤー (UI レイヤー、ビジネス レイヤー、データ レイヤー) に分割することは、最もよくある間違いです。

❌ Technical Decomposition (SAI):
├── frontend-service
├── backend-service
├── database-service
└── notification-service

✅ Domain Decomposition (ĐÚNG):
├── user-management (UI + API + DB cho User)
├── product-catalog (UI + API + DB cho Product)
├── order-processing (UI + API + DB cho Order)
└── payment (UI + API + DB cho Payment)

1.2 DDD は何を解決しますか?

  • ユビキタス言語: チーム全体 (開発、PM、ビジネス) が同じ「言語」を話します。
  • 境界コンテキスト: ドメイン間の明確な境界を定義します。
  • 結合を減らす: 境界のある各コンテキストは独立した単位です
  • ビジネスとテクノロジーの連携: アーキテクチャはビジネス構造を反映します

2. 戦略的 DDD — 全体像を見る

2.1 ユビキタス言語

各境界コンテキストには独自の 言語 があります。同じ「製品」という単語ですが、文脈ごとに意味が異なります。

┌───────────────────┐  ┌──────────────────┐  ┌──────────────────┐
│  Product Catalog   │  │   Order Context  │  │  Shipping Context│
│                    │  │                  │  │                  │
│ Product:           │  │ OrderItem:       │  │ Parcel:          │
│ - name, desc       │  │ - productId      │  │ - weight         │
│ - price, images    │  │ - quantity       │  │ - dimensions     │
│ - categories       │  │ - unitPrice      │  │ - tracking       │
│ - reviews          │  │ - discount       │  │ - destination    │
└───────────────────┘  └──────────────────┘  └──────────────────┘

Cùng "Product" nhưng mỗi context cần thông tin khác nhau!

2.2 境界付きコンテキスト

境界コンテキスト は、一貫したドメイン モデルが適用される論理境界です。

原則:

  • 各境界付きコンテキスト = 1 つのマイクロサービス (または小さなグループ)
  • 各境界付きコンテキスト = 1 つのマイクロ フロントエンド (または UI の一部)
  • コンテキスト間: API またはイベント を介して通信します (共有データベースは使用しません!)

2.3 コンテキストマッピング

境界付きコンテキストは独立して存在するのではなく、互いに 関係 を持っています。

Context Map:
┌──────────────┐          ┌──────────────┐
│   Product    │◄─────────│    Order     │
│   Catalog    │ Upstream  │  Processing  │
│  (Supplier)  │──────────►│ (Consumer)   │
└──────────────┘          └──────┬───────┘
                                 │
                          ┌──────┴───────┐
                          │   Payment    │
                          │   Gateway    │
                          └──────────────┘

関係パターン:

パターン説明いつ使用するか
顧客とサプライヤー上流は提供し、下流は消費する明示的な依存関係
共有カーネルモデルの一部を共有する2 つのコンテキストは密接に関連しています。
腐敗防止層2 つのモデル間のレイヤー遷移レガシー システム統合
公開言語通信用の標準 API/スキーマ多くの消費者は

3. 戦術的 DDD — 設計の詳細

3.1 集計

集約は、一貫性の単位として扱われる エンティティのグループ です。すべての変更は 集約ルート を経由します。

Order Aggregate:
┌─────────────────────────────────┐
│  Order (Aggregate Root)         │
│  ├── OrderItem                  │
│  ├── OrderItem                  │
│  └── ShippingAddress            │
│                                 │
│  Invariants:                    │
│  - Total = sum(items.price)     │
│  - Status transitions are valid │
│  - At least 1 item required     │
└─────────────────────────────────┘

3.2 ドメインイベント

ドメイン イベントでは、ドメイン内で発生した イベントについて説明します。

// Domain Events
interface OrderPlaced {
  orderId: string;
  customerId: string;
  items: OrderItem[];
  totalAmount: number;
  placedAt: Date;
}

interface PaymentConfirmed {
  paymentId: string;
  orderId: string;
  amount: number;
  confirmedAt: Date;
}

// Event flow
OrderPlaced → PaymentService listens → PaymentConfirmed → ShippingService listens

4. イベントストーミング — ドメイン検出

4.1 イベント ストーミングとは何ですか?

イベント ストーミングは、開発者とドメインの専門家が付箋を貼り付けて一緒にドメインを探索するワークショップです。

Timeline: ─────────────────────────────────────────────►

🟧 Domain Event     🟦 Command          🟨 Policy/Rule
"Order Placed"     "Place Order"       "If payment fails,
                                        cancel order"

🟪 Aggregate        🟩 External System   🔴 Hot Spot
"Order"            "Payment Gateway"   "Race condition
                                        when checking stock"

4.2 イベントストーミングから境界付きコンテキストへ

ワークショップの後、関連イベントをグループ化→境界コンテキストを定義→マイクロサービス + マイクロ フロントエンドにマッピングします。

Event Storming Results → Bounded Contexts:
├── Product Context: ProductCreated, ProductUpdated, CategoryChanged
├── Cart Context: ItemAddedToCart, CartAbandoned, CouponApplied
├── Order Context: OrderPlaced, OrderConfirmed, OrderShipped
├── Payment Context: PaymentInitiated, PaymentConfirmed, RefundIssued
└── User Context: UserRegistered, ProfileUpdated, AddressAdded

Mapping:
├── Product Context → Product Microservice + Product MFE
├── Cart Context    → Cart Microservice + Cart MFE
├── Order Context   → Order Microservice + Checkout MFE
├── Payment Context → Payment Microservice (no separate MFE)
└── User Context    → User Microservice + Account MFE

5. DDD をマイクロフロントエンドに適用する

5.1 境界付きコンテキスト → マイクロフロントエンド

各境界コンテキストは 1 つのマイクロサービスにマップされるだけでなく、1 つのマイクロ フロントエンドにもマップされます。

Bounded Context: Product Catalog
├── Backend: Product Microservice
│   ├── REST API / GraphQL
│   ├── PostgreSQL database
│   └── Search index (Elasticsearch)
│
├── Frontend: Product Micro Frontend
│   ├── Product listing page
│   ├── Product detail page
│   ├── Search & filter UI
│   └── Product reviews
│
└── Team: Product Team (full-stack ownership)

5.2 DDD に基づくチーム トポロジ

┌──────────────────────────────────────────┐
│              Organization                │
├──────────┬──────────┬────────┬───────────┤
│ Team     │ Team     │ Team   │ Team      │
│ Product  │ Cart     │ Order  │ Platform  │
├──────────┼──────────┼────────┼───────────┤
│ MFE:     │ MFE:     │ MFE:   │ Shell App │
│ Product  │ Cart     │ Order  │ Design Sys│
│ pages    │ sidebar  │ pages  │ Auth      │
├──────────┼──────────┼────────┼───────────┤
│ µS:      │ µS:      │ µS:    │ API GW    │
│ Product  │ Cart     │ Order  │ Infra     │
│ API      │ API      │ API    │           │
├──────────┼──────────┼────────┼───────────┤
│ DB:      │ DB:      │ DB:    │ Shared    │
│ Postgres │ Redis    │ Postgres│ Services │
└──────────┴──────────┴────────┴───────────┘

概要

  • DDD はシステムを適切に分解するための思考基盤です
  • 境界コンテキスト で境界を定義 → マイクロサービス + マイクロ フロントエンドにマップ
  • イベント ストーミング は、ビジネス専門家とのドメイン探索に役立ちます
  • コンテキスト マッピング はコンテキスト間の関係を定義します
  • (技術レイヤーごとではなく) ドメイン で分割することが黄金律です

次の記事: レッスン 3: フルスタックのアーキテクチャの概要 — マイクロサービス + マイクロ フロントエンド + BFF