集約とは
集約とは、それぞれのエンティティや値オブジェクトを、どういう単位で作成したり削除したりするか、といったことをあらわす。
エンティティや値オブジェクトの設計と比較して、どういう集約をつくるか、という設計は環境によってもさまざまなパターンがあり得て、開発を進めながら増やしたり減らしたりといったことがおきやすいとおもわれる。
集約の基本ルール
・集約にはルートとなるエンティティがひとつ存在し、外部から集約内のオブジェクトにアクセスするときはルートを経由しておこなう。
・集約の外から集約内部への参照をすることはできないが、集約の外部へ向けて値を渡すだけであれば許容される。
ルールの背景
集約とはオブジェクトをつくったり消したりする単位であるが、そもそもなぜいくつかのオブジェクトをまとめてつくったり消したりするかといえば、それはそれらのオブジェクトはシステムにとって、まとまっていて初めて意味をなすからとおもわれる。
制御する意味のある単位をあらわすのが集約であり、外部からそのまとまり全体を指し示して処理を命令することを可能にするために、命令の受け手となるオブジェクトをルートとして定義する。
集約はおおきくなりがち
まずはトランザクションの単位で集約をザックリつくっていくのがよさそう。
でもそうすると場合によっては集約に含まれるオブジェクトが多くなってしまい、メモリやデータベースの性能面で問題が発生する可能性がある。
そのため、いったんつくった集約を小さくすることができないか検討する。
集約同士の関連
集約同士のつながりを表現するには、集約のルートエンティティを外部の集約ルートエンティティが直接アクセスするのではなく、値オブジェクトを使って関連を表現したほうがいいとおもわれる。
これは、エンティティと違って値オブジェクトは不変なので、意図しない操作をあらかじめ防げるからである。
しかし場合によっては、値オブジェクトをつかった外部の集約ルートへのアクセスは、その属性にアクセスできないことでオーバーヘッドが生じることもあるので、ここも開発を通じてたびたび変更がはいることはありえるとおもわれる。
結果整合性
集約を分割した場合には、それらの集約は同一のトランザクションで整合性をとらないため、かわりに結果整合性を確保する。
これは、ある集約のトランザクションが実行されたことをトリガーにしてイベントを発行し、それを別の集約に通知してトランザクションを実行する整合性のとりかたである。
同一トランザクションでの整合性はとれないが、そのかわりに集約を小さくして複雑さを軽減し、リソースの節約に資すると判断できるときには選択する。