8

Prenez cet exemple simple, artificiel:Objet de référentiel, de service ou de domaine - d'où vient la logique?

UserRepository.GetAllUsers(); UserRepository.GetUserById();

Inévitablement, je vais avoir plus complexes « requêtes », telles que:

//returns users where active=true, deleted=false, and confirmed = true 
GetActiveUsers(); 

Je vais avoir du mal à déterminer où la responsabilité du dépôt se termine. GetActiveUsers() représente une simple "requête". Appartient-il du référentiel?

Que diriez-vous quelque chose qui implique un peu de logique, comme:

//activate the user, set the activationCode to "used", etc. 
ActivateUser(string activationCode); 

Répondre

3

Les référentiels sont responsables de la gestion spécifique à l'application des objets des objets. Cela couvre naturellement les requêtes ainsi que les modifications (insérer/supprimer).

ActivateUser fonctionne sur un seul objet. Cet objet doit être récupéré, puis modifié. Le référentiel est responsable de récupérer l'objet de l'ensemble; une autre classe serait responsable de l'invocation de la requête et de l'utilisation de l'objet.

2

Ce sont toutes d'excellentes questions à poser. Être en mesure de déterminer lequel de ces vous devez utiliser se résume à votre expérience et le problème que vous travaillez.

Je suggère de lire un livre tel que patterns of enterprise architecture de Fowler. Dans ce livre, il discute des modèles que vous mentionnez. Plus important encore, il attribue à chaque motif la responsabilité. Par exemple, la logique de domaine peut être placée dans les couches Service ou Domaine. Il y a des avantages et des inconvénients associés à chacun.

Si je décide d'utiliser une couche Service, j'assigne à la couche le rôle de gestion des transactions et des autorisations. J'aime rester mince et ne pas avoir de logique de domaine. Il devient une API pour mon application. Je conserve toute la logique métier avec les objets du domaine. Cela inclut les algorithmes et la validation de l'objet. Le référentiel récupère et conserve les objets de domaine. Cela peut être un mappage un à un entre les colonnes de la base de données et les propriétés du domaine pour les systèmes simples.

Je pense que GetAtcitveUsers est ok pour le Repository. Vous ne voudriez pas récupérer tous les utilisateurs de la base de données et déterminer ceux qui sont actifs dans l'application car cela conduirait à de mauvaises performances. Si ActivateUser a une logique métier comme vous le suggérez, cette logique appartient à l'objet domaine. La persistance du changement est la responsabilité de la couche Repository.

Espérons que cela aide.

+0

En réponse à votre dernier paragraphe: Que faire si "persister le changement" est la seule logique. par exemple. ActivateUser() met simplement à jour un enregistrement dans la table User et un enregistrement dans la table ActivationCode. Est-ce que cela constitue une "logique"? Si non, que fait-il? – betitall

2

Lors de la construction de projets DDD, j'aime différencier deux responsabilités: un référentiel et un Finder.

Un référentiel est responsable du stockage des racines agrégées et de leur récupération, mais uniquement pour l'utilisation dans le traitement des commandes. Par traitement de commande, j'entendais l'exécution de toute action invoquée par un utilisateur.

Un Finder est responsable de l'interrogation des objets de domaine à des fins d'interface utilisateur, comme les vues de grille et les vues détaillées.

Je ne considère pas les chercheurs comme faisant partie du modèle de domaine.Les interfaces IXxxFinder particulières sont placées dans la couche de présentation, pas dans la couche de domaine. L'implémentation de IXxxRepository et de IXxxFinder est placée dans la couche d'accès aux données, peut-être même dans la même classe.

Questions connexes