📄
概念 📚 software-design-concepts

ドメインモデリング

DDD(ドメイン駆動設計)の中核概念と、境界づけられたコンテキスト・エンティティ・値オブジェクトの設計指針

ドメインモデリングとは、業務の概念・ルール・プロセスをコードで表現する設計活動である。DDD(Domain-Driven Design)はエリック・エヴァンスが体系化した手法で、技術的な正確さよりもビジネスドメインの本質的な複雑さへの対応を優先する。開発者とドメイン専門家が共通の語彙(ユビキタス言語)を使って会話し、その言語を直接コードに反映させることで、モデルと実装の乖離を防ぐ。

境界づけられたコンテキスト(Bounded Context)はDDDの中核概念であり、ユビキタス言語が一貫して通用する範囲を定義する。同じ「顧客」という概念でも、受注コンテキストと請求コンテキストでは異なるデータ・ルールを持つ場合があり、それぞれのコンテキスト内で独立したモデルを持つほうが設計として健全である。エンティティは同一性(identity)によって識別されるオブジェクトであり(例: Order は ID で識別される)、値オブジェクト(Value Object)は属性の組み合わせで定義され不変(immutable)であるべきオブジェクトである(例: Money、Address)。

集約(Aggregate)はトランザクション整合性の単位であり、集約ルート(Aggregate Root)を通じてのみ内部オブジェクトへのアクセスを許可する。集約の境界を正しく設計することで、ロックの競合を最小化しながらビジネスルールの不変条件(invariant)を維持できる。集約は一つのトランザクションで一つだけ変更するという原則(One Aggregate per Transaction)が推奨される。

コードレビューで着目するポイント

  • ユビキタス言語がコード(クラス名・メソッド名・変数名)に忠実に反映されているか
  • エンティティが本当に同一性による識別を必要とするか(値オブジェクトで表現すべき概念ではないか)
  • 値オブジェクトが不変(immutable)として設計されているか(setter が存在していないか)
  • 集約ルートを経由せずに集約内部のエンティティへ直接アクセスしていないか
  • 集約の境界が適切か(大きすぎる集約はロック競合の原因、小さすぎる集約は整合性維持が困難)
  • 異なる Bounded Context 間の通信がコンテキストマップ(ACL・共有カーネルなど)の設計に基づいているか
  • ドメインサービスとアプリケーションサービスの責務が明確に分離されているか

典型的なアンチパターン

貧血ドメインモデル(Anemic Domain Model): エンティティがデータの入れ物(getter/setter のみ)として機能し、ビジネスロジックがサービス層に分散している状態。オブジェクト指向の恩恵を受けられず、ドメインルールの所在が不明確になる。

大きすぎる集約: 多くのエンティティを一つの集約に含め、トランザクションスコープが広がりすぎる設計。同時更新によるロック競合や、不必要なデータロードによるパフォーマンス問題を引き起こす。

Bounded Context の無視: 複数のコンテキストで同一のドメインオブジェクトを共有し、一方の変更が他方に影響を与える密結合な設計。変更の影響範囲が読めなくなり、リファクタリングコストが増大する。

参考リソース

  • 『ドメイン駆動設計』Eric Evans(翔泳社)
  • 『実践ドメイン駆動設計』Vaughn Vernon(翔泳社)
  • 『Domain Modeling Made Functional』Scott Wlaschin(Pragmatic Bookshelf)
  • DDD Reference(https://domainlanguage.com/ddd/reference/)
  • 『IDDDシリーズ』Vaughn Vernon(同シリーズの concepts_iddd_*.md も参照)