little-hands/ddd-q-and-a

valueオブジェクトについて2点質問です。1.基本的に、エンティティが持つフィールドとなるものは、業務上意味のある単位である可能性が高いためvalueオブジェクトにしておいた方が良いのかなと思っていますが如何でしょうか。2.ユースケース層...

Opened this issue · 0 comments

Question

valueオブジェクトについて2点質問です。
1.基本的に、エンティティが持つフィールドとなるものは、業務上意味のある単位である可能性が高いためvalueオブジェクトにしておいた方が良いのかなと思っていますが如何でしょうか。
2.ユースケース層がエンティティ内部のvalueオブジェクトの関数を呼び出したい時、直接entity.value.hogehoge()とすると抽象度が下がってしまうような気がします。この場合、entityに間を取り持つ関数を用意するべきでしょうか。

Answer

1.必ずしもそうとは言い切れません。メリットデメリットを考慮して判断しましょう。値オブジェクトをくくり出すメリットは、ドメインの知識が対応するクラスで表現できて高凝集・低結合になること、タイプセーフになることです。
小さなデメリットとはクラスが増えることで、多少ならば基本的に問題ありませんが、クラス数が10個とかになってくると流石にクラス数、ファイル数の増加でコードが追いにくくなります。
このバランスを考えると、表現する知識がないのに常に値オブジェクトにする、という必要はなく、そのオブジェクトに詰め込みたい知識がある場合に値オブジェクトをくくりだす、ぐらいの考え方が良いと思います。

2は、値に取り持つ関数を持った時にその関数の責務が明確か、可読性が高まるか、という判断基準で考えましょう。
例えばUserクラスがMailAddress値オブジェクトを内包しており、MailAddress.isValidFormat()というメソッドがあったとします。これをラップしてUser.isEmailAddressValidFormat()というメソッドを持ったとして、このメソッドの責務は何でしょうか?例えば「ユーザーは有効なメールアドレスを持っていれば有効ユーザーである」といった判断に使うのであればいいかもしれません。ただし、その場合は「User.isValidUser」といった責務にあったメソッド名にした方が良いでしょう。そのようなUserクラスが表現する知識がなく、ただ内部メソッドを呼ばせたくないだけの場合、もしかすると責務が不明瞭なメソッドになってしまうかもしれません。その場合はEmailAddressクラスを返して直接メソッドを呼ばせるという選択肢もありだと思います。