エンティティと値オブジェクト
DDDにおける「エンティティ」とは一意なものを表現する概念です。一意であるため、長期にわたって変化できるオブジェクトとなります。例えば「社員」というエンティティの場合、社員番号で社員を一意に識別することで、同じ人物であることを把握し、住所や所属といった属性を適切に変更できます。なお、一意に識別して変更を管理する必要がないものは「値オブジェクト(6章にて紹介)」として取り扱います。
DDDでよくある失敗
DDDで設計を始めてみると、データの格納方法ばかり気になってしまうことがよくあります。このようなERモデリング(テーブル構成とリレーション関係)を先に検討されたエンティティは、DB項目のプロパティしか存在しない機能不足なモデル「ドメインモデル貧血症」になりがちです。ドメインモデル貧血症とは、オブジェクト指向設計の基本である「データと処理を一緒に取り扱う」ことを行わない、単なる手続き型設計のことです。一見、ドメインモデルと同じような構造を持ちつつも、オブジェクトの「振る舞い」が不足している状態を指します。
そのため、DDDで設計する場合には、DOA(データ中心アプローチ)のようにデータ中心で検討するのではなく、OOA(オブジェクト指向アプローチ)のような振る舞いも含めたモデルから検討する方法が適しています。
また、エンティティは「オブジェクトの区別が必須」であるケースにおいて使用する概念です。しかし実際には、値オブジェクトで十分なものをエンティティとして設計してしまう失敗があります(もし、エンティティが多数を占める単純なCRUDシステムであれば、DDDの採用自体が間違っている可能性もあります。このような場合にはDDDを採用せず、普通に開発したほうがよいでしょう)。
モデリングとエンティティ発見の流れ
先ほど述べたようにDDDでの設計は(DB設計ではなく)オブジェクトモデリングを中心に進めていきます。エンティティの発見と検討の流れは次の通りです。
- [1]ソフトウェア要件の理解
- [2]モデリングを検討しエンティティを抽出
- [3]エンティティを識別する属性と振る舞いを検討
-
[4]「一意な識別子」の設計
- 一意な識別子の生成方法
- 一意な識別子の生成タイミング
- [5]エンティティの振る舞い(メソッド)を検討
- [6]エンティティの作成方法(コンストラクタ/ファクトリ)を検討
- [7]エンティティのバリデーションを検討
IDDD本では、SaaSOvationのサンプルを用いて「認証・アクセスコンテキスト」の「ユーザー」や「テナント」に対してモデリングと実装(Java/C#)を検討しています。それでは順に見ていきましょう。
[1]ソフトウェア要件の理解
設計を始めるにあたり、まず業務内容から整理していきます。開発する対象業務について、ドメインエキスパートから要望を聞き出していきます。ここでは業務仕様を「簡単なソフトウェア要件」という形で書き出しています(難易度によりますが、「ユースケース」や「ユーザーストーリー」といった成果物を作成し、要件の明確化を行ってもよいでしょう)。
[2]モデリングを検討しエンティティを抽出
次に、チームで共通のユビキタス言語を構築することを意識して、ドメインエキスパートと十分な議論を行います。なお、ユビキタス言語を見つける流れについては、第1章の説明もご確認いただければと思います。
エンティティの検討
エンティティの抽出においては、シナリオにおいて「変更」というキーワードがある箇所に注目します。主語の用語がエンティティとなる可能性が高くなります。SaaSOvationでは「テナント」と「ユーザー」をエンティティの候補として選択しています。
[コラム]DDD本におけるエンティティの解説
IDDD本では、エンティティの解説として、エヴァンス氏の次の説明を引用しています。
あるオブジェクトが属性ではなく同一性によって識別されるのであれば、モデルでこのオブジェクトを定義する際には、その同一性を第一とすること。クラスの定義をシンプルに保ち、ライフサイクルの連続性と同一性に集中すること。形式や履歴に関係なく、各オブジェクトを識別する手段を提供すること。…(中略)…モデルは、同じものであるということが何を意味するかを定義しなければいけない。
属性やふるまいに集中するよりは、エンティティオブジェクトの定義を、最も本質的な特徴にまでそぎ落とすこと。特にエンティティを識別するものや、それを検索し突き合わせるのに通常使用されるものが、そういう本質的な特徴だ。つけ加えるのはその概念にとって本質的なふるまいと、そのふるまいが必要とする属性だけにすること。
モデリングをしていると細かい属性と振る舞いに気を取られがちですが、エヴァンス氏の言葉にあるように、エンティティの同一性に注目しシンプルに保つことが重要だと思われます。