あべぶろ

気になった技術の備忘録を残します。

【ドメイン駆動設計】EntitiyとVO(Value Object)の違い

概要

現在ドメイン駆動設計を勉強しており、EntitiyとVO(Value Object)の違いがよく分からないので自分なりに纏めてみる。

ドメイン駆動

業務での関心事(ドメイン)を中心にアプローチしていく設計手法。
ドメインに注視して設計していくため、設計を進める事で要件を深堀出来たり、
将来的な仕様追加に柔軟に対応出来るシステムを作る事が出来る。
ドメイン駆動設計をする際は、OOA(オブジェクト思考アプローチ)を使って進めて必要がある。
今までDOA(データ中心アプローチ)によるシステム設計を経験してきた自分からすると結構戸惑う。

OOA(オブジェクト思考アプローチ)

自分のOOAのイメージはこんな感じ、「データ + 振る舞い」
各オブジェクトは自身にデータを保持しており、
またそれを利用者にどう見せるか、どうデータを変化させるかという振る舞いを持っている。
こうする事でデータモデルが変わったとしても、利用者側には影響を出さずに要件を満たす事が出来る。

Entity

話を戻してEntityについて記載する。
ドメイン駆動におけるEntityとはある関心事の中で一意に表現すべき概念のこと。
また、Entityは自身の状態が変化するという特性を持っている。
要件の中で状態が変更する概念はEntityとして管理すべきである。

VO(Value Object)

一方VOは状態は持っておらず、その時点で決まる固定値を格納するために利用する。
また、Entityを補足説明する物であるのでEntityとセットで使用する(...と思う)。
VOを利用するメリットとしては、固定値を加工して返却したり、複数のEntityで概念を共有する事が出来る。

IDDD本によるとVOは以下のように定義されている。

  • そのドメイン内の何かを計測したり定量化したり、あるいは説明したりする。
  • 状態を不変に保つことができる。
  • 関連する属性を不可欠な単位として組み合わせることで、概念的な統一体を形成する。
  • 計測値や説明が変わったときには、全体を完全に置き換えられる。
  • 値が等しいかどうかを、他と比較できる。
  • 協力関係にあるその他の概念に、副作用のない振る舞いを提供する。

個人的にはこの定義が好きである(?)
例えばVOでも値を変更したりすることは普通にあると思う。
その場合は、値を変更するのではなくオブジェクト全体を書き換えることを推奨している。

  • 計測値や説明が変わったときには、全体を完全に置き換えられる。