全体像

ドメイン駆動設計(DDD)は、業務の知識をそのままソフトウェアの形にするための考え方です。 どこで線を引くかを決める戦略的設計と、線の内側をどう作るかを決める戦術的設計の 2 つに分かれ、その両方を業務の言葉(ユビキタス言語)がつなぎます。このページでは EC の注文システムを例に、それぞれを図で見ていきます。

境界づけられたコンテキスト

1 つの巨大なモデルで業務全体を表そうとすると、言葉の意味がぶつかって破綻します。そこで、 1 つのモデルが通用する範囲で線を引きます。これが境界づけられたコンテキストです。 注文システムなら、注文・在庫・配送・決済は別々のコンテキストになり、イベントや API でやりとりします。

下のコンテキストマップは、サブドメインの種類ごとに枠を分けています。

ユビキタス言語

同じ「商品」という言葉でも、コンテキストによって関心がまったく違います。無理に 1 つのクラスにまとめず、コンテキストごとに別のモデルとして持つのが DDD の考え方です。 コンテキストの中では、業務の人と開発者が同じ言葉を同じ意味で使い、コードの名前にもそのまま使います。

コンテキスト 「商品」が意味するもの モデルが持つもの
注文 カートに入れて買うもの 商品ID · 注文時点の価格 · 数量
在庫 倉庫の棚にあるもの SKU · 倉庫ごとの在庫数 · 引当数
配送 箱に詰めて運ぶもの 重さ · サイズ · 温度帯

集約

集約は一緒に整合性を守るオブジェクトのまとまりです。「注文の合計金額は明細の合計と一致する」 のようなルールは、集約の中で必ず守られます。外からはルート(ここでは Order)だけを触り、他の集約は ID で参照します。

Order 集約
Order(集約ルート) 状態 · 合計金額を持ち、明細の追加やキャンセルはすべてここを通す
OrderLine エンティティ · 注文明細。Order の外では意味を持たない
Money 値オブジェクト · 金額と通貨
ShippingAddress 値オブジェクト · 配送先の住所
Customer 集約 customerId で参照
Product(価格) productId で参照
  1. 1 つのトランザクションで更新するのは 1 つの集約だけ。
  2. 集約をまたぐ整合性は、ドメインイベント(例: OrderPlaced)で後から合わせる。
  3. 集約は小さく保つ。迷ったら分けて、ID で参照する。