DDD(ドメイン駆動設計)と重要用語について解説します
DDD(ドメイン駆動設計)とは
DDD(ドメイン駆動設計)とはエリック・エバンズさんが提唱したユーザーが従事する業務に合わせてソフトウェアを解決する手法です。
ユーザーファーストの考え方は常識となりましたが、それを実現するための開発手法をどうするか、その手法の1つがDDD(ドメイン駆動設計)ということです。
下記にて、DDD(ドメイン駆動設計)とは何なのかをwikipediaから引用致しました。
ドメイン駆動設計(英: domain-driven design, DDD)とはソフトウェアの設計手法であり、「複雑なドメインの設計は、モデルベースで行うべき」であり、また「大半のソフトウェアプロジェクトでは、システムを実装するための特定の技術ではなく、ドメインそのものとドメインのロジックに焦点を置くべき」であるとする。
要はドメインの知識に焦点をあてた設計手法のことですね。
参考図書 – ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本
DDDのメリット
DDDについてなんとなく理解はできたかと思います。
では、DDDの4つの利点について解説致します。
業務ごとに機能を分離する
1つの大きなシステムのため、プログラムが肥大化しやすいため、ドメインとコンテキストを適切に分離し、業務ごとに機能を分離し解決します。
永続化ストレージを分離する
大規模なシステムとDBで構築をしていると永続化層が肥大化するため、ドメインとコンテキストを適切に分離し、永続化ストレージを分離し解決します。
顧客と開発者の実装内容のずれを防ぐ
全システムを対象の設計者が上流工程で時間をかけて仕様について検討し、その設計書通りにプログラマが開発をする手法だと、顧客が求める機能と速度感にずれが発生してしまう可能性があります。
顧客と開発者で共通の言葉「ユビキタス言語」で会話した通りに実装することで解決します。
変化に強い
業務ごとに機能を分離しているため、実装すべきコードが比較的少なくすみます。
DDD(ドメイン駆動設計)における用語の説明
DDDには専門的な用語が多々出てきます。下記にてDDDに頻繁使用される用語の説明を行います。
ドメイン
まずは設計の名前にも入っているドメインから説明致します。
ドメインは「領域」の意味を持った言葉で、ソフトウェア開発におけるドメインは「プログラムを適用する対象となる領域」を指します。
モデル
モデルとは現実の事象あるいは概念を抽象化した概念です。
ドメインモデル
事象や概念を抽象化する作業がモデリングと呼び、その結果として得られるものがドメインモデルとなります。
ドメインオブジェクト
ドメインモデルをソフトウェアで動作するモジュールとして表現したものがドメインオブジェクトです。
知識を表現するパターン
値オブジェクト(バリューオブジェクト)
ドメイン固有の概念(金銭や製造番号など)を値として表現するパターンです。
代表的な値の性質
- 不変である
- 交換が可能である
- 等価性によって比較される
値オブジェクトはシステム固有の値の表現であり、値の一種です。値が持つ性質は値オブジェクトにそのまま反映されます。
エンティティ
エンティティは値オブジェクトと同じくドメインの概念を表現するオブジェクトですが、値オブジェクトと対を為すような性質があります。
エンティティの性質
- 可変である
- 同じ属性であっても区別される
- 同一性により区別される
判断基準
値オブジェクトとエンティティはドメインの概念を表現するオブジェクトとして似ています。値オブジェクトかエンティティのどちらにするかという判断基準はライフサイクルが存在し、そこに連続性が存在するかどうかが大きな判断基準になるそうです。
もし、ユーザーという概念を値オブジェクトかエンティティで迷っていた場合に、ユーザーは作成されたときに生を受け、削除される際に死を迎えるので、連続性のある概念です。
なので、ユーザーという概念はエンティティ。という判断です。それ以外はひとまず値オブジェクトとして判断するという考え方で問題ないかと思います。
ドメインサービス
ドメインサービスは値オブジェクトやエンティティではうまく表現できない知識を取り扱うためのパターンです。
ただ、全てのふるまいをドメインサービスへ移設することも可能ではありますが、なるべく値オブジェクトやエンティティで上手く表現できない知識を取り扱うことに注力しましょう。
ふるまいを値オブジェクトやエンティティに定義すべきか、ドメインサービスに定義すべきか迷ったらドメインサービスに定義しましょう。ドメイン貧血症を起こしてしまいます。
アプリケーションを実現するためのパターン
リポジトリ
リポジトリはデータの保存や復元といった永続化や再構築を担当するオブジェクトです。
データの永続化はリレーショナルデータベースなどの具体的なデータストアが思い浮かびますが、リポジトリはそれらを抽象化します。
わかりやすく言うと
「DB関連の操作はここで!」
みたいな認識です。
アプリケーションサービス
アプリケーションサービスはドメインオブジェクトを強調させてユースケースを実現します。
値オブジェクトやエンティティといったドメインオブジェクトはドメインモデルをコードによって表現しておりますが、アプリケーションサービスはそれらをまとめてタスクを管理し、問題の解決に導きます。
ファクトリ
オブジェクトの生成は複雑な手順を必要としますが、モデルを表現するオブジェクトを無理やり実装するよりも、オブジェクトの生成自体を独立したオブジェクトとする方がコードの意図を明確人することに繋がります。
ファクトリはそのオブジェクトを生成する責務を持ったオブジェクトです。
知識を表現するの発展パターン
集約
集約は変更の単位です。
データを変更するための単位として使われるオブジェクトの塊を集約と言います。集約にはルートとなるオブジェクトが存在し、操作は全てルートを介して行われます。ルート越しのため集約内部への操作には制限がかけられ、集約内の不変条件は維持されます。
仕様
仕様はオブジェクトの評価を行うオブジェクトです。
オブジェクトの評価は時に複雑な手順が必要となりますが、こうした評価処理をオブジェクトのメソッドとして定義すると、オブジェクトの本来の趣旨が理解しずらくなります。評価処理はオブジェクトに定義する以外に評価自体をオブジェクトとして切り出すことが可能です。