web-dev-qa-db-fra.com

DAO, référentiels et services en DDD

Après avoir lu plusieurs articles, je commence à comprendre la différence entre DAO et les référentiels, mais j'ai du mal à essayer de comprendre la différence entre les référentiels et les services.

Pour faire court, dans le paradigme OO:

  • [~ # ~] dao [~ # ~] : classe qui contient le CRUD operations pour une classe d'entité. Il a le code nécessaire pour obtenir ou récupérer des éléments du système de stockage persistant sous-jacent. De manière générale, les méthodes reçoivent des entités objet en tant que paramètres, sauf dans la méthode retrieve où l'utilisation d'un type d'identifiant est valide.

  • Référentiels : Dans un niveau d'abstraction plus élevé .. comme j'ai généralement lu est une sorte d'endroit où mettre du code qui gère les opérations sur les objets agrégés (objets qui avoir des objets enfants). Il utilise les DAOs pour récupérer des objets de la base de données, et à la fin il expose une interface dans le langage "métier" du domaine. (Mais encore une fois, je pense qu'il est très valable d'utiliser des types de données d'identifiants). Exemple: un addSomething très simple où something est un objet enfant du parent dont les instances, btw, sont gérées dans leur ensemble par le référentiel.

  • Services : Encore une fois, c'est à un niveau d'abstraction plus élevé. À mon humble point de vue, ils sont un bon endroit pour connecter deux classes qui ne partagent pas la relation parent-enfant, mais sont aussi loin (en termes d'abstraction) que Repository. Exemple: La méthode transferCash entre deux bank accounts.

Donc, ce sont mes lectures, mais je demande ici que les pensées ci-dessus soient bonnes ou non. Ou comment je devrais penser. Ou quelque chose qui me fait comprendre vraiment la différence de tous ces concepts.

Quelques sources:

30
Victor

Les référentiels sont - comme vous le dites - une abstraction. Ils proviennent de Martin Fowler Object Query Pattern . Les référentiels et les DTO peuvent simplifier la persistance de la base de données en mappant les données persistantes à une collection équivalente d'objets d'entité. Cependant, les référentiels sont plus grossiers que les DAO en fournissant le contrôle d'un Aggregate Root (AG) cachant souvent beaucoup d'état interne au client. D'un autre côté, les DAO peuvent être aussi fins que dédiés à un objet entité unique. Pour les référentiels et les DAO, il est courant d'utiliser Hibernate ou d'autres cadres de mappage objet/relationnel (ORM) au lieu d'écrire votre propre implémentation.

En règle générale, les services peuvent résider dans une couche de service et peuvent agir à la fois comme façade de fonctionnalité, couche anti-corruption et coordinateur pour la mise en cache et la transaction. Ils sont souvent un bon endroit pour effectuer l'exploitation forestière. Services à grain grossier et orientés vers les cas d'utilisation, par ex. Service.updateCustomerAdress() ou Service.sendOrder(). Les référentiels peuvent être trop fins pour être consommés par les clients, par ex. Customer.add(…), Order.modify(…).

Les référentiels et les DAO ont le même objectif: conserver les données de manière permanente. Les services, en revanche, ne doivent pas tenir compte de la persistance et n'ont aucune connaissance de votre base de données. Ils travaillent généralement en étroite collaboration avec les services de domaine, les référentiels et le cœur de domaine.

23
Magnus Backeus

Les référentiels sont des interfaces de stockage et de récupération Racines agrégées (AR) , pas des entités uniques. Vous avez un référentiel pour chaque AR de votre modèle de domaine.

Selon Fowler Repository Pattern , les référentiels agissent comme une collection d'objets en mémoire et c'est l'une des principales différences en les comparant aux DAO.

Les interfaces de référentiels sont un moyen pour le client du modèle de domaine (et font donc partie du modèle de domaine) de commencer à travailler avec le modèle de domaine. Les clients sont destinés à obtenir une instance AR à partir d'un référentiel, appeler une méthode sur celui-ci, qui modifie généralement son état interne, puis la stocker à nouveau dans le référentiel.

14
Enrico Sanguin

Je ne sais même pas ce qu'est "DAO". Les référentiels sont une abstraction pour charger des entités. Vous devriez pouvoir obtenir une entité et en enregistrer une, c'est tout. Pas d'interrogation. Si vous souhaitez interroger certaines données, écrivez une requête (peut-être même dans une méthode d'action MVC, ou avec la plus simple des abstractions simples permettant à certains SQL d'être exécutés et à certains DTO retournés qui peuvent être rendus directement dans le HTML).

Les services en revanche sont délicats. Pour commencer, le terme est surchargé. Les "services d'application" tels que définis par livre DDD par Eric Evans existent parce que les objets du modèle de domaine ne sont pas autorisés à accéder aux problèmes d'infrastructure comme les bases de données, la messagerie, la mise en cache, etc. Ils ont besoin de tout cela pour et les leur a remis sur une plaque, et les services d'application font exactement cela. Les services applicatifs, quant à eux ne contiennent aucune logique . Je ne m'attendrais pas à voir ICustomerService.ChangeAddress() faire autre chose que:

  1. Chargez l'entité Client.
  2. Appeler Customer.ChangeAddress(newAddress) <- cela encapsule la logique du domaine
  3. Sauvez le client.
  4. Peut-être publier certains événements.

Si vous avez un service qui charge un client, en définissant sa propriété Address et en l'enregistrant, ce service est en fait un script de transaction et le client est un DTO. Cela signifie que vous avez certainement une abstraction qui fuit et que vous avez probablement un modèle de domaine anémique. Les objets de modèle de domaine ne doivent pas avoir de setters publics, et lorsque DDD est combiné avec CQRS, votre modèle de domaine peut même ne pas avoir d'état public au-delà des valeurs d'ID d'entité principales.

3
Neil Barnwell