ドメインモデルにおいて、マスタ情報はエンティティか値オブジェクトか


設計の指針で迷いがあるので、教えてください。

下記の要件を含むTODO管理ツールを作っているとします。

  1. ユーザは、作成したタスク（Taskと命名）に色（TaskColorと命名）を付けることができる。
  2. TaskColorは、TaskColorマスタに登録されたものから選んで、Taskに設定する。
  3. TaskColorマスタは、ユーザが自分で内容を変更できる。

TaskColorは、下記の情報を持ちます。

  * 色コード：RGBとか
  * 意味：ユーザが任意で設定できる文字列、メモのようなもの

私の認識では、エンティティか値オブジェクトかの判断を下すには、もう少し要件が必要です。

（１）TaskColorマスタの「意味」や「色コード」を変えると、全ての作成済みTaskに付けられたTaskColorにも変更が反映される場合  
各Taskに設定されたTaskColorの同一性を追跡できる必要があるため、エンティティではないかと考えています。  
また、TaskColorには識別子（TaskColorId）を付け、TaskにはTaskColorIdだけを持たせることになりそうです。

（２）TaskColorマスタを変更しても、作成済みTaskに反映しなくて良い場合  
単純にこれだけなら、Taskの永続化の際に、TaskColorの属性値も一緒に埋め込んでしまえるので、TaskColorは値オブジェクトで良さそうに思えます。  
しかし、Taskに埋め込まれるまでは、TaskColorマスタ上でそれぞれのTaskColorの同一性が確保されているような気がして、少しもやもやしています。  
とはいえ、ここで私が感じている同一性は、TaskColorの用途において同一性の確保が必要とされたものではなく、結果的に同一性があるっぽく見えているだけの幻、とも思えます。

他にもケースはあるとは思いますが、まず上記（１）と（２）について、それぞれどのように考えるのが、ドメインモデルとして正解なのでしょうか？




エリックエバンスのドメイン駆動設計(DDD)の文脈で考えると、次のようになると思います。

（１）ＩＤを持たせて、属性は変更されることを想定する

これは、エンティティですね。

DDD では、エンティティを、「参照オブジェクト(Reference Object)」とも呼んでいます。  
IDなどの識別情報を手がかりに、なんらかの情報を「参照」する場合の設計は、基本的にエンティティとして設計を検討するのが良いと思います。

この例だと、別のIDだが、同じ色や同じメモを持ってもよいかどうかとか、ユーザが認識するID（識別情報）は、何か。それから、TaskColor
自体を追加したり削除するときのID体系をどうするか、とか、バージョン管理まで必要か ... など、エンティティらしい議論がいろいろでてきそうです。

（２）変更をタスクに反映しない場合

こちらは、値オブジェクトでしょう。

考え方としては、値が同じであれば、別のオブジェクトでも同一視してよければ、それは値オブジェクトですね。  
逆に言えば、値（たとえば色）が同じでも、別モノ、という区別をしたいのなら、それは、エンティティになると思います。

ちょっと話はずれますが、(1)のエンティティの方向で設計するなら、TaskColor は、個人的には、TaskType とか TaskCategory
のほうがしっくりきます。Colorは識別の手段の一つ。識別したいことは「色」というよりは、タスクの「種類」とか「グループ」なのかなあ、ということです。

参考になれば幸いです。




エリックエバンスのドメイン駆動設計(DDD)の文脈で考えると、次のようになると思います。

（１）ＩＤを持たせて、属性は変更されることを想定する

これは、エンティティですね。

DDD では、エンティティを、「参照オブジェクト(Reference Object)」とも呼んでいます。  
IDなどの識別情報を手がかりに、なんらかの情報を「参照」する場合の設計は、基本的にエンティティとして設計を検討するのが良いと思います。

この例だと、別のIDだが、同じ色や同じメモを持ってもよいかどうかとか、ユーザが認識するID（識別情報）は、何か。それから、TaskColor
自体を追加したり削除するときのID体系をどうするか、とか、バージョン管理まで必要か ... など、エンティティらしい議論がいろいろでてきそうです。

（２）変更をタスクに反映しない場合

こちらは、値オブジェクトでしょう。

考え方としては、値が同じであれば、別のオブジェクトでも同一視してよければ、それは値オブジェクトですね。  
逆に言えば、値（たとえば色）が同じでも、別モノ、という区別をしたいのなら、それは、エンティティになると思います。

ちょっと話はずれますが、(1)のエンティティの方向で設計するなら、TaskColor は、個人的には、TaskType とか TaskCategory
のほうがしっくりきます。Colorは識別の手段の一つ。識別したいことは「色」というよりは、タスクの「種類」とか「グループ」なのかなあ、ということです。

参考になれば幸いです。

