Payments
のリストを返すAPI呼び出しがあります。各Payment
にはUser
が含まれています。それを呼び出して、結果をデータベースに保存し、すべての支払いとユーザーをフェッチして、それらすべてをプレゼンターに返す必要があります。 UIの各支払い行には、ユーザーに関する情報も含まれます。したがって、Payment
およびUser
エンティティは、私の場合、高度に結合されています。
私のアイデアは、PaymentRepository
とGetPaymentsUseCase
を作成することでした。この場合、リポジトリはPayment
とUser
の両方のテーブルにアクセスできるため、両方をクエリして両方に挿入できます。ただし(間違っている場合は修正してください)、クリーンなアーキテクチャの原則では、すべてのリポジトリが1つのエンティティに対して責任を負うべきであると述べています。
しかし、私の場合、この呼び出しを2つのリポジトリ間で分離しても意味がありません。私がそうすることに決めた場合、PaymentRepository
とUserRepository
は互いにアクセスしてはならないので、ユースケースはそれらの両方を呼び出し、データを相互にマッピングした後にそれらの間でデータを受け渡す必要があります。私の考えではひどいようです。
私のソリューションは受け入れられますか、それともクリーンなアーキテクチャの原則に違反しますか?もしそうなら、これを実装する方法について何か提案はありますか?
リポジトリは、エンティティをコアとして識別する「 クリーンアーキテクチャ 」を壊しません。依存関係の反転が必要ですが、リポジトリの使用を強制しません。
しかし、あなたのリポジトリはクリーンなコードの原則を破っているようで、特に:
Payment
(たとえば、新しい商慣行や新しい銀行基準により変更される可能性があります)およびUser
(内部ポリシー、GDPRの懸念事項、またはIDプロバイダーの要件に従います);Payment
とUser
のインターフェースを必要としない場合でも、それらを知るように強制します(たとえば、後で使用する場合)先月の1日あたりの支払いの合計に関するレポートを作成します)。あなたのアプローチは、単一のAggregateのリポジトリを示唆する Domain Driven Design の原則と一致していないようです。
DDDでは、Entitiesを識別し、それらを独立したAggregatesにグループ化します。これらは常に単一のAggregate Root。
しかし、あなたの場合、2つの独立したエンティティがあり、それぞれが独自の集約を構成しています。
Payment
は、依存するUser
を含む集合体と見なすことはできません。後者は、支払いが行われる前に存在する可能性があるためです。User
を従属Payments
のある集合体と見なすこともできません。これは、ユーザーに関してのみ支払いを特定できることを意味します。これは現実的な支払いのケースではありません。システム。編集:追加情報
リポジトリの概念は、メモリ内のコレクションにあるかのように永続オブジェクトを処理できるようにする抽象化のレベルを提供することを目的としています。
このアーキテクチャパターンでは、他の集計 identity(value) を参照します。典型的なシナリオは、Payments
をクエリしてPaymentRepository
を取得することです。次に、支払いのUserId
を使用して、UserRepostitory.getById()
でユーザーを取得します。または、UserRepostitory.getByPaymentId()
を呼び出して、PaymentId
を使用して支払いのユーザーにクエリを実行することもできます。
IDの利点は、非常に複雑なモデルでエンティティを分離できることです。(単純なIDの代わりに)考えられるすべての種類のオブジェクトをリポジトリに渡すと、インターフェースの依存関係が急増します。同様に、関連するオブジェクトが体系的にリポジトリに読み込まれると(予想どおり)、スノーボール効果が発生する可能性があります。グラフのノードとエッジを表すエンティティがあるとします。リポジトリから取得するノードが何であれ、完全なグラフがメモリに格納されます。
そうは言っても、私はあなたのモデルもあなたの制約も知りませんし、私も判断しません。最も適切なアーキテクチャを決定するのはあなた次第です。有効な引数があり、その結果を理解している場合は、規則から完全に逸脱する可能性があります。ちなみに、リポジトリのパフォーマンスについて この質問 に興味があるかもしれません。