コンテンツにスキップ

ドメイン駆動設計

starlightBlog.tags.count

DDD のリポジトリ記事を追加しました

DDD における リポジトリ(Repository) について、基本的な役割を整理した解説ドキュメントと、Kotlin での実装例をまとめたドキュメントを追加しました。

リポジトリは、ドメインオブジェクトを保存したり、再び取り出したりするための窓口です。
ドメインモデルを DB や SQL の都合から切り離すうえで重要な部品ですが、DAO との違いや、どこまで検索処理を持たせるべきかで迷いやすい部分でもあります。

これまでの DDD 関連ドキュメントでは、値オブジェクト、エンティティ、ドメインサービスを中心に整理してきました。

一方で、ドメインサービスの記事の中では UserRepositoryPartyRepository のようなリポジトリが登場しています。
そのため、先に「リポジトリとは何か」を独立した記事として整理しておくと、今後の集約やアプリケーションサービスの記事にもつなげやすいと考えました。

今回の記事では、リポジトリを単なる DB アクセス部品としてではなく、ドメインオブジェクトを取得・保存するためのインターフェース として扱う考え方をまとめています。

リポジトリの解説記事では、主に次の内容を扱っています。

  • リポジトリとは何か
  • なぜドメイン層と永続化の詳細を分けるのか
  • DAO とリポジトリの違い
  • DB レコードではなくドメインオブジェクトを返す理由
  • 何でも検索できるクラスにしないための注意点
  • リポジトリを集約ルート単位で扱う考え方

Kotlin での具体的なコード例は、実装例ドキュメントとして分けています。

特に、Repository を findByXxx が増え続ける便利な検索クラスにしないこと、更新に必要な取得と画面表示のための検索を分けて考えることを意識して書いています。

DDD の基本要素から順番に読む場合は、先に エンティティ値オブジェクト を読むと理解しやすいと思います。

そのうえで、ドメインオブジェクトを保存・取得する必要が出てきたときに、今回の リポジトリ の記事を読み、実装の形を確認したくなったら Kotlinでのリポジトリ実装例 に進む流れを想定しています。

また、リポジトリは今後まとめる予定の 集約 とも関係が深い概念です。
今回の記事では集約については軽く触れるだけにし、リポジトリを集約ルート単位で扱う理由は別の記事で改めて整理する予定です。

リポジトリの記事を追加したことで、DDD の基本的な部品として、値オブジェクト、エンティティ、ドメインサービス、リポジトリまでを一通り確認できるようになりました。

次は、これらのドメインオブジェクトをどの範囲でまとめるかを考える 集約 について整理していく予定です。
また、読み取り処理と更新処理を分ける考え方である CQRS についても、リポジトリとは別のテーマとして今後まとめていきます。

ドメインサービスの記事を公開しました

ドメインサービス の記事を公開しました。

DDD を学んでいると、エンティティや値オブジェクトにルールを置く、という考え方は比較的イメージしやすい一方で、「どちらにも自然に置きにくいルール」をどう扱うかで迷いやすいと感じています。

今回の記事では、その置き場所としての ドメインサービス について、基本的な考え方を整理しました。
Kotlin での具体的な実装例は、別のドキュメントとして分けています。

DDD では、ドメインルールをできるだけドメイン層に表現することが大切です。

ただ、実際に実装していると、単一のエンティティや値オブジェクトだけでは判断できないルールが出てきます。
たとえば、ユーザー名がシステム全体で一意かどうか、プレイヤーがすでに別のパーティーに所属していないか、といった判断です。

こうしたルールをアプリケーションサービスに直接書いてしまうと、ユースケースの手順とドメイン上の制約が混ざりやすくなります。
また、同じ判断が複数のユースケースに散らばると、ルールの変更にも弱くなります。

そこで、エンティティや値オブジェクトに自然に置けないドメインルールを、ドメインサービスとして切り出す考え方をまとめました。

ドメインサービスの記事では、主に次の内容を扱っています。

  • ドメインサービスとは何か
  • なぜアプリケーションサービスにルールを書きすぎない方がよいのか
  • 一意性の確認や複数集約をまたぐ判断をどう扱うか
  • ドメインサービスを使うべきケースと避けるべきケース

Kotlin での具体的なコード例は、実装例ドキュメントとして分けています。

特に、ドメインサービスを「便利な共通処理置き場」にしないこと、エンティティ自身が判断できるルールまでサービスへ逃がさないことを意識して書いています。

DDD の基本要素から順番に確認する場合は、先に エンティティ値オブジェクト を読むと理解しやすいと思います。

そのうえで、複数のオブジェクトをまたぐルールや、リポジトリへの問い合わせが必要なドメイン判断が出てきたときに、今回の ドメインサービス の記事を読み、実装の形を確認したくなったら Kotlinでのドメインサービス実装例 に進む流れを想定しています。

また、ドメインサービスの呼び出し漏れを構造的に防ぎたい場合の応用として、ダブルディスパッチ の記事にもつながるようにしました。

DDD の基本的なドメインオブジェクトを整理するときの参考になればうれしいです。

DDD 入門ドキュメントを作成しました

ドメイン駆動設計(DDD)入門|ドメイン・ドメインオブジェクト・ドメインモデルの違い を公開しました。

DDD を学び始めると「ドメイン」「ドメインオブジェクト」「ドメインモデル」など似た用語が並び、最初の一歩でつまずきやすいと感じていたので、入門用のドキュメントとして整理しました。自分も当初は「ユーザードメイン」「商品ドメイン」のように、エンティティ単位のものをドメインだと勘違いしていたので、そのあたりも含めて、用語の違いがつかみやすい内容にしています。

ネットショップや SNS の具体例を交えながら、次の 4 つを解説しています。

  • ドメイン … アプリが再現しようとしている現実の仕事・ルール
  • ドメインオブジェクト … ドメインの要素をプログラムで表現した部品
  • ドメインモデル … ドメインオブジェクトを組み合わせた全体設計
  • ドメイン駆動設計(DDD) … ルールを一か所にまとめてプログラムを組み立てる考え方

DDD 関連ドキュメントの入口として置いています。気づきやフィードバックがあれば、ぜひ教えてください。