私はドメイン駆動設計(DDD)の概念に飛び込んでいますが、特にドメインと永続性モデルの分離に関して、いくつかの原則が奇妙であることに気付きました。これが私の基本的な理解です:
- (機能セットを提供する)アプリケーション層のサービスは、その機能を実行するために必要なリポジトリからドメインオブジェクトを要求します。
- このリポジトリの具体的な実装は、それが実装されたストレージからデータをフェッチします
- サービスは、ビジネスロジックをカプセル化するドメインオブジェクトに、その状態を変更する特定のタスクを実行するように指示します。
- サービスは、変更されたドメインオブジェクトを永続化するようリポジトリに指示します。
- リポジトリは、ドメインオブジェクトをストレージ内の対応する表現にマップする必要があります。
さて、上記の仮定を考えると、以下は厄介なようです:
広告2 ::
ドメインモデルは、ドメインオブジェクト全体(すべてのフィールドと参照を含む)をロードしているように見えます。それを要求した関数には必要ない場合でもです。他のドメインオブジェクトが参照されている場合は、それらのドメインオブジェクトとそれらが参照しているすべてのオブジェクトを順にロードしない限り、完全にロードすることさえ不可能かもしれません。遅延読み込みが思い浮かびますが、これは、最初にリポジトリの責任であるドメインオブジェクトのクエリを開始することを意味します。
この問題を考えると、ドメインオブジェクトをロードする「正しい」方法には、各ユースケースに専用のロード関数があるようです。これらの専用関数は、それらが設計されたユースケースで必要なデータのみをロードします。ここで、ぎこちないことが出てきます。最初に、リポジトリの実装ごとにかなりの量のロード関数を維持する必要があり、ドメインオブジェクトはnull
、フィールドを運ぶ不完全な状態になってしまいます。後者は、値がロードされなかった場合でも、それを要求した機能によって要求されるべきではないため、技術的には問題になりません。それでも厄介で潜在的な危険です。
広告3 ::
ドメインオブジェクトは、リポジトリの概念がない場合、構築時に一意性の制約をどのように検証しますか?たとえばUser
、一意の社会保障番号(指定されている)を使用して新しいを作成する場合、データベースに一意性制約が定義されている場合にのみ、リポジトリにオブジェクトの保存を要求すると、最も早い競合が発生します。それ以外の場合はUser
、指定された社会保障でを探し、それが存在する場合は、新しいものを作成する前にエラーを報告できます。ただし、制約チェックはサービスに存在し、それらが属するドメインオブジェクトには存在しません。私はドメインオブジェクトが検証のために(注入された)リポジトリを使用することが非常によく許可されていることに気づきました。
広告5 .:
私は、ドメインオブジェクトのストレージバックエンドへのマッピングを、ドメインオブジェクトが基になるデータを直接変更するのと比較して、作業集約的なプロセスとして認識しています。もちろん、具体的なストレージ実装をドメインコードから切り離すことは、必須の前提条件です。しかし、それは確かにそのような高コストで来るのでしょうか?
ORMツールを使用してマッピングを行うオプションがあるようです。ただし、ORMの制限に従ってドメインモデルを設計する必要がある場合や、ドメインからインフラストラクチャレイヤーへの依存関係を導入する必要がある場合もあります(たとえば、ドメインオブジェクトでORMアノテーションを使用するなど)。また、私はORMがかなりの計算オーバーヘッドをもたらすことを読みました。
ORSQLのような概念がほとんど存在しないNoSQLデータベースの場合、ドメインモデルで変更されたプロパティをどのように追跡しますsave()
か?
編集:また、リポジトリがドメインオブジェクトの状態(つまり、各フィールドの値)にアクセスするためには、ドメインオブジェクトがカプセル化を解除する内部状態を明らかにする必要があります。
一般に:
- トランザクションロジックはどこに行きますか?これは確かに永続化に固有のものです。一部のストレージインフラストラクチャは、トランザクションをまったくサポートしない場合もあります(インメモリモックリポジトリなど)。
- 複数のオブジェクトを変更する一括操作の場合、オブジェクトのカプセル化された検証ロジックを通過するために、各オブジェクトを個別にロード、変更、および保存する必要がありますか?これは、データベースに対して単一のクエリを直接実行することとは対照的です。
このトピックについて、いくつかの説明をお願いします。私の仮定は正しいですか?そうでない場合、これらの問題に取り組む正しい方法は何ですか?