ValueObject
ビジネスロジック
において用いられるさまざまな
値
を表現するもの.
「金額=単価*数量」であれば,「金額」「単価」「数量」が
ValueObject
である.
設計モデル
的な話
プリミティブ型
は
システム
に最適な
値
の表現ではないため,
クラス
によって
ラップ
して
ValueObject
とすることで利用する.
値
の性質とは
不変
である.
パフォーマンス
の観点から
不変
が難しい場合は,
可変
にしても良い.
しかし,迷うなら
不変
にしておこう.
asRagi.icon
C#
なら
構造体
を利用すれば
アロケーション
は防げそう.
交換可能である.
等価性
によって比較される.
比較
のための
メソッド
を
ValueObject
が提供する必要がある.
ValueObject
は
データ
の
コンテナ
ではなく,振る舞いも定義される.
加算
処理など.
加算
された
値
を持つ
ValueObject
を返す.
例外
をここで早出するなど.
ValueObject
に定義されない振る舞いは
ValueObject
にできないことであると言える.
ValueObject
の数だけ
クラス
が生まれる
心理的ハードル
がある.
導入のモチベーション
表現力が増す.
string modelNumber
ではなく,
ModelNumber modelNumber
であれば,
modelNumber
が何者であるかがわかる.
できる操作や概念は
ModelNumber
に全て書かれている.
ドキュメント
たりえる. ->
自己文書化
不正な
値
の存在を未然に防ぐ.
ValueObject
で
バリデーション
ができる.
誤った
代入
を防ぐ.
string name
を
User.Id
に
代入
する操作が正しいかどうかは
仕様
による.
User.Id
が
UserId
型
であれば,
string name
の
代入
が
コンパイルエラー
になって嬉しい.
UserId
の
ValueObject
が
バリデーション
を実行できる.
ロジック
の散在を防ぐ.
ValueObject
の新規作成と更新処理それぞれの
バリデーション
を一箇所にまとめられる.
どこまでを
ValueObject
にするべきかの問題がある.
FullName
を構成する
FirstName
,
LastName
はそれぞれ
ValueObject
にするべきか?
文脈によるが,どちらも間違っているとは言えない.
閉じた操作