J'ai un appel d'API qui renvoie une liste de Payments
, chaque Payment
contient un User
. Je dois l'appeler, enregistrer les résultats dans la base de données, récupérer tous les paiements et utilisateurs et les renvoyer tous au présentateur. Sur l'interface utilisateur, chaque ligne de paiement contiendra également des informations sur l'utilisateur. Les entités Payment
et User
sont donc fortement couplées dans mon cas.
Mon idée était de créer PaymentRepository
et GetPaymentsUseCase
. Dans ce cas, le référentiel a accès aux tables Payment
et User
, il peut donc les interroger toutes les deux et les insérer dans les deux. Cependant (corrigez-moi si je me trompe), les principes d'architecture propre stipulent que chaque référentiel doit être responsable d'une entité.
Mais dans mon cas, cela n'a vraiment aucun sens de séparer cet appel entre 2 repos. Si je décide de le faire, les PaymentRepository
et UserRepository
ne devraient pas accéder les uns aux autres, donc le cas d'utilisation devrait les appeler tous les deux et passer des données entre eux après les avoir mappés d'avant en arrière, ce qui a l'air terrible à mon avis.
Ma solution est-elle acceptable ou brise-t-elle les principes de l'architecture propre? Si oui, y a-t-il des suggestions sur la façon de mettre en œuvre cela?
Votre référentiel ne casse pas le " architecture propre ", qui identifie les entités comme le noyau, nécessite une inversion de dépendance, mais n'impose pas d'utiliser des référentiels.
Mais votre référentiel semble rompre les principes du code propre, et en particulier:
Payment
(qui pourrait changer par exemple en raison de nouvelles pratiques commerciales ou de nouvelles normes bancaires) et User
(soumis à la politique interne, aux préoccupations du RGPD ou aux exigences du fournisseur d'identité);Payment
et User
, même s'ils n'en ont pas besoin (par exemple si un cas d'utilisation ultérieur produirait un rapport sur le total des paiements par jour le mois dernier).Votre approche ne semble pas non plus conforme aux principes Domain Driven Design , qui suggèrent un référentiel pour un seul agrégat:
Dans DDD, vous identifiez Entités et les regroupez en Aggregates qui sont des objets auxquels il faut toujours accéder via un seul Aggregate Root.
Mais dans votre cas, vous avez deux entités indépendantes qui constituent chacune leur propre agrégat:
Payment
comme un agrégat contenant un User
dépendant, car ce dernier peut exister avant d'avoir effectué un paiement.User
comme un agrégat dépendant Payments
, car cela signifierait que vous ne pourriez identifier un paiement que par rapport à un utilisateur, ce qui n'est pas un cas réaliste de paiement systèmes.Edit: infos supplémentaires
Le concept de référentiel vise à fournir un niveau d'abstraction qui vous permet de gérer des objets persistants comme s'ils étaient dans une collection en mémoire, et sans transporter la base de données.
Avec ce modèle architectural, vous préférez référencer d'autres agrégats par identité (valeur) . Le scénario typique consiste à obtenir Payments
en interrogeant le PaymentRepository
. Ensuite, le UserId
du paiement serait utilisé pour obtenir l'utilisateur avec UserRepostitory.getById()
. Ou vous pouvez simplement utiliser le PaymentId
pour interroger un utilisateur d'un paiement avec en appelant UserRepostitory.getByPaymentId()
.
L'avantage de l'identité est qu'elle permet de découpler des Entités dans des modèles très complexes: passer tous les types d'objets possibles à un référentiel (au lieu d'un simple identifiant) provoquerait une explosion des dépendances d'interface. De même, si des objets liés étaient systématiquement chargés par le référentiel (comme vous pensez vous y attendre), vous pourriez avoir un effet Snowball: imaginez que vous auriez des entités représentant les nœuds et les bords d'un graphique. Quel que soit le nœud que vous obtiendrez du référentiel, vous vous retrouveriez avec le graphique complet en mémoire!
Ceci dit, je ne connais pas votre modèle ni vos contraintes et je ne juge pas. C'est à vous de décider quelle est l'architecture la plus adaptée. Vous pouvez parfaitement dévier des règles si vous avez des arguments valides et comprenez les conséquences. Soit dit en passant, cette question sur les performances du référentiel peut vous intéresser.