ValueObjectとは?
クラスプロパティにプリミティブ型ではなくオブジェクトとして定義する。
class User{ int volume; // プリミティブ型 Volume volume; // ValueObject }
メリット整理
- 型安全、null安全、値安全を構築しやすい
- コンストラクタでフィルターできる。
- privateなプリミティブ型でsetterアクセスでもいいのでは?
- 複数のクラスで配置されるような情報だと凝縮性が下がってしまう。
- ある程度の「使われ方」を制御できる。
- 例えばintのプリミティブ型だと
+ - * /
などのint演算が自由に定義側で行えるが、クラスインターフェースにすることで、インクリメント、デクリメントすることしかできない値のような定義として扱うことができる。 - このケースでも各クラスで計算されるよりValueObject側で計算した方が凝縮性が高くなる。
- 例えばintのプリミティブ型だと
特に型安全は大きなメリットと感じた。
継承は機能の拡張、ValueObjectはどちらかというとtypeof
なので役割が全く違う。
とはいえ...
ドメイン設計でコンテキスト境界を引いた、予約、注文、受け取りなど、商品名を持つオブジェクトに対して、予約品名、注文品名、キャンセル品名、受け取り品名などの各コンテキスト名をValueObjectにするの?という煩雑性があったりする。
個人的には、こういったケースではプリミティブ型で各定義クラスに実装を書くでもいいと思うし、汎用なオブジェクトで委譲してもいいんでないかな。という感想。