ドメイン駆動設計(DDD)ってなに?第2回:エンティティと値オブジェクトで混乱した話

前回、DDDを建物にたとえてざっくり見てみました。
今回は、その中でよく出てくる「エンティティ」と「値オブジェクト」ってやつについて、ぜんぜんピンとこなかったので、あらためて整理してみたメモです。
混乱ポイント1:どっちも「データの入れ物」じゃないの?
まず思ったのが、「どっちもプロパティの入ったクラスって感じなんだけど、なにが違うの?」ってこと。
エンティティ=本人であることが重要なやつ
たとえば「社員Aさん」は、部署が変わったり、名前が変わってもAさんはAさん。
これは“本人”として追跡する必要があるやつ=エンティティ。
→ たとえばIDなどで区別されるもの。
履歴を持たせたい場合などもエンティティになるみたい。よく考えたら当然かも。IDがないと誰の履歴かわからなくなりますもんね。
値オブジェクト=中身がすべてのやつ
たとえば住所「北海道札幌市〜」は、まったく同じ住所なら、誰が使っても意味は同じ。
これは値オブジェクトって考えるらしい。
→ 使いまわしOKで、中身が同じなら同一とみなせる。
「Aさん」という存在はその人だから意味がある。
一方で「北海道札幌市」という住所は、誰が使っても同じ意味。
そう考えると、「エンティティは“その人じゃないと困るもの”」「値オブジェクトは“コピーしてOKな情報”」っていう見方ができる気がしてきました。
値オブジェクトにするべきものとは?
とはいっても何でもかんでも値オブジェクトにしてはキリがないのでは・・。調べてみると必要なものだけで良さそうです。例えば住所を表示するために「住所オブジェクト」をつくるなどですかね。
なぜこれが必要かというと、、
たとえば「住所」ひとつとっても、
- 都道府県
- 市町村
- 番地
- 建物名
この4つを、決まった順番で表示したいというルールがあるとします。
さらに、「数字はすべて半角で揃えたい」といった見た目の統一ルールもあったりします。
こういうときに、住所オブジェクトの中でそのルールを保証してくれると、めちゃくちゃ安心なんですよね。
逆にもしこういうオブジェクトがないと、
- 都道府県の入力を忘れる
- 番地の数字だけ全角になる
といった事故がばらばらに起こる可能性が出てきます。
そんな時に専用オブジェクトを用意しておけば、
半角に自動で変換する
- 足りない値のチェックをする
- 表示フォーマットを統一する
などの振る舞いを一箇所に集約できて、結果として事故が起きにくい設計になるわけです。
なるほど……これが値オブジェクトの効果なんですね。
実際にクラスとして切り出すのは、
- チェックしたいルールがある
- その情報に“まとまり”としての意味がある
という場合だけ。
つまり、ドメインの事情で意味があるときだけ、値オブジェクトとして実体化するという感じのようです。
まとめ
まだまだふわっとしてますが、「エンティティと値オブジェクトって何が違うの?」というところが、ちょっとずつ整理できてきた気がします。
次は「この情報たちを、どこでまとめて面倒見るのか?」――つまり集約ルート(受付窓口)について、自分なりに調べてみようと思います!
→ 続き:「全部この窓口を通して!集約ルート(受付窓口)」へ続きます!