質問: 現在、DDD でアプリケーションの作成を試みています。初めての取り組みなので、いろいろつまずいているのですが、首題の件で質問があります。 DDD では、状態の保持はリポジトリを用いて行うのかなという認識です。 その際、DB を用いずに、メモリ上で一時的に保存する必要がある場合の、 in-memory リポジトリ(オンメモリリポジトリ?)の実装方法について悩んでいます。 基本的にリポジトリで保存したり取得したりする対象は集約ルートになると思うのですが、集約ルートは参照型になると思います。 愚直に実装すると、参照型をそのままリポジトリ上に保持することになるので、取得時にオブジェクトの再構築が不要になります。(というか再構築のしようがない) この場合、取得したオブジェクトの状態を変更すると、参照型でそのままオブジェクトを取得するため、オブジェクトがダイレクトに変更されます。 Web 上や IDDD 本に出てくる例では、`リポジトリはコレクションのようにして扱えるようにする` というのがよく挙がっています。つまり、 `Add` や `Update` など、明示的な API をコールしたときに初めてリポジトリが更新されるという認識です。 そのため、上記のダイレクトで変更が反映される点に違和感があります。 そこで、メモリ上に集約ルートを保存する場合の実装方法としては、どのようなやり方がよいのでしょうか。 ご助力いただければ助かります。宜しくお願い致します。
回答: 私の場合、in-memory リポジトリは主にテストの目的で使っているので、特に不都合がない場合は、エンティティの参照をそのまま in-memory リポジトリにに入れています。 それで不都合が生じる場合には、in-memoryリポジトリへの格納と、in-memory リポジトリからの Entity 取得で deep copy が働くように、in-memory リポジトリを実装します。 あるいは、in-memory ではない、アプリケーション用のリポジトリにシリアライズ処理がある場合(KVSにjsonを格納するなど)は、それを踏襲して in-memory リポジトリを実装する場合もあります。 また、テストの為だけに全てのリポジトリに対して in-memory リポジトリを実装するのは面倒なので、テスト環境の方で工夫して(テスト時に必ず MySQL や redis を立ち上げる、など)、in-memory リポジトリを作らない場合もあります。 テスト以外の目的で in-memory リポジトリを使った経験がなく、用途をあまり思いつかないのですが、実装方針は上に書いたのとほぼ同じになりそうです。