Accesso a più entità nel repository: architettura pulita

2

Ho una chiamata API che restituisce un elenco di Payments , ogni Payment contiene un User . Devo chiamarlo, salvare i risultati nel database, recuperare tutti i pagamenti e gli utenti e restituirli tutti al presentatore. Sull'interfaccia utente ogni riga di pagamento conterrà anche informazioni sull'utente. Quindi le entità Payment e User sono altamente accoppiate nel mio caso.

La mia idea stava creando PaymentRepository e GetPaymentsUseCase . Il repository in questo caso ha accesso a entrambe le tabelle Payment e User , quindi può interrogare entrambi e inserire in entrambi. Tuttavia (correggimi se sbaglio) i principi di architettura pulita stabiliscono che ogni repository dovrebbe essere responsabile di una entità.

Ma nel mio caso non ha senso separare questa chiamata tra 2 repository. Se decido di farlo, PaymentRepository e UserRepository non dovrebbero accedersi l'un l'altro, quindi il caso d'uso dovrebbe chiamarli entrambi e passare i dati tra di loro dopo averlo mappato avanti e indietro, il che sembra terribile secondo me .

La mia soluzione è accettabile o infrange i principi dell'architettura pulita? Se sì, ci sono suggerimenti su come implementarlo?

    
posta Joseph Jreij 11.09.2018 - 14:47
fonte

1 risposta

0

Il tuo repository non interrompe " architettura pulita ", che identifica le entità come il nucleo, richiede l'inversione di dipendenza, ma non impone l'uso di archivi.

Ma il tuo repository sembra infrangere i principi del codice pulito, e in particolare:

  • il principio di responsabilità singola : impacchetta cose che hanno motivi diversi modificare: Payment (che potrebbe cambiare ad esempio a causa di nuove pratiche commerciali o nuovi standard bancari) e User (soggetto a politica interna, dubbi di GDPR o requisiti del provider di identità);
  • il principio di separazione delle interfacce : tu costringi i client del tuo repository a conoscere l'interfaccia di Payment e User , anche se non ne hanno bisogno (ad esempio se un caso di utilizzo successivo produrrebbe un rapporto sul totale dei pagamenti al giorno nell'ultimo mese) .

Il tuo approccio non è in linea con i principi Domain Driven Design , che suggeriscono un repository per un singolo aggregato :

  • In DDD identificate Entità e raggruppate in Aggregati indipendenti che sono sempre accessibili tramite una singola radice aggregata .

  • Ma nel tuo caso, hai due Entità indipendenti che costituiscono ciascuna il proprio Aggregato:

    • Non è possibile vedere Payment come un aggregato contenente un User dipendente, poiché quest'ultimo potrebbe esistere prima di aver effettuato qualsiasi pagamento.
    • Non è possibile considerare User come un aggregato con Payments dipendente, perché ciò significherebbe che è possibile identificare un pagamento solo in relazione a un utente, che non è un caso realistico per i sistemi di pagamento.

Modifica: informazioni aggiuntive

Il concetto di repository intende fornire un livello di astrazione che consente di gestire oggetti persistenti come se fossero in una raccolta in memoria e senza eseguire il db.

Con questo modello architettonico, preferisci fare riferimento ad altri aggregati per identità (valore) . Lo scenario tipico è ottenere Payments interrogando PaymentRepository . Quindi verrà utilizzato UserId del pagamento per ottenere l'utente con UserRepostitory.getById() . In alternativa, devi utilizzare PaymentId per interrogare un utente di un pagamento invocando UserRepostitory.getByPaymentId() .

Il vantaggio dell'identità è che consente di separare le Entità in modelli molto complessi: passare tutti i possibili tipi di oggetti a un repository (invece di un semplice id) causerebbe un'esplosione di dipendenze dell'interfaccia. Allo stesso modo, se gli oggetti correlati verrebbero caricati sistematicamente dal repository (come pensate di aspettarvi), allora potreste avere un effetto valanga: immaginate di avere entità che rappresentano nodi e bordi di un grafico. Qualunque sia il nodo che si ottiene dal repository, si finirebbe con il grafico completo in memoria!

Detto questo, non conosco il tuo modello né i tuoi vincoli e non giudico. Sta a voi decidere quale sia l'architettura più adatta. Puoi discostarti perfettamente dalle regole se hai argomenti validi e comprendi le conseguenze. A proposito, questa domanda sulle prestazioni del repository potrebbe interessarti.

    
risposta data 12.09.2018 - 01:33
fonte