最近の個人的な関心ごととしてドメイン駆動を意識した開発業務でビジネスロジックを「値オブジェクト」、「エンティティ」、「サービス」にどう分割していくのが良いのか。というのがあり、この辺り整理するために「ドメイン駆動設計入門」を読んで整理してみました。
ほぼ自分のためのメモです。
値オブジェクト
値の性質
- 不変である
- 交換が可能である
- 等価性によって比較される
値オブジェクトにする基準
値オブジェクトにする基準として筆者は「ルールがあるか」と「それ単体で取り扱たいか」を挙げている。
例えば氏名には「姓と名で構成される」というルールがある。また本書のサンプルコードでは単体で取り扱っている。 そのためこの基準に照らし合わせると値オブジェクトとして定義される。
「姓や名」で考えるとシステム上の制限はなく姓だけを取り扱ったり名だけを取り扱ったりすることはなさそうなので値オブジェクトとして定義はしない。
ふるまい
値オブジェクトには独自のふるまいを定義できる
お金を値オブジェクトとして定義すると量と通貨単位(円やドル)の属性を持つ。そして加算というふるまいを持たせて通貨単位が異なる場合は例外を発生させることができる。
値オブジェクトを採用するモチベーション
- 表現力を増す
- 不正な値を代入させない
- 謝った代入を防ぐ
- ロジックの散在を防ぐ
エンティティ
エンティティの性質
エンティティの性質は値とは真逆で - 可変である - 同じ属性であっても区別される - 同一性によって区別される
可変である
例えばユーザオブジェクトであればユーザネームをふるまい(ChangeNameメソッド)によって変更できる。 値オブジェクトは不変なので交換(代入)によって変更を表現するがエンティティは交換によって変更を表現しない。
同じ属性であっても区別される
氏名の値オブジェクトであれば同じ氏名のものは同じオブジェクトとして扱われるが人間を表現するエンティティであれば同じ名前でも違うオブジェクトとして区別される。区別には識別子を使う。
同一性を持つ
ユーザは名前を変えても同一のユーザとして扱われる。
サービス
エンティティや値オブジェクトに記述すると不自然なものはサービスに記述する。
すべてのふるまいはドメインサービスに記述できてしまうがなるべく値オブジェクトやエンティティに記述する方が良い。 ドメインサービスの濫用はデータとふるまいを断絶させロジックの点在を促してしまう。