511 votes

Quelle est la différence entre les modèles DAO et Repository ?

Quelle est la différence entre les modèles Data Access Objects (DAO) et Repository ? Je développe une application en utilisant Enterprise Java Beans (EJB3), Hibernate ORM comme infrastructure, et Domain-Driven Design (DDD) et Test-Driven Development (TDD) comme techniques de conception.

585voto

qes Points 11681

DAO est une abstraction de persistance des données .
Repository est une abstraction de une collection d'objets .

DAO serait considéré comme plus proche de la base de données, souvent centré sur les tables.
Repository serait considéré comme plus proche du domaine, ne s'occupant que des racines de l'agrégat.

Repository pourrait être mis en œuvre en utilisant DAO mais vous ne feriez pas le contraire.

En outre, un Repository est généralement une interface plus étroite. Il doit s'agir simplement d'une collection d'objets, avec une fonction Get(id) , Find(ISpecification) , Add(Entity) .

Une méthode comme Update est approprié sur un DAO mais pas un Repository - lors de l'utilisation d'un Repository Les modifications apportées aux entités sont généralement suivies par une unité de travail distincte.

Il semble courant de voir des implémentations appelées un Repository qui est en fait plus une DAO C'est pourquoi je pense qu'il existe une certaine confusion quant à la différence entre les deux.

0 votes

Ok, mais d'habitude, le code pour les DAO abstraits et le référentiel est très similaire, n'est-ce pas ?

0 votes

@Thurein : Il semble courant de voir un référentiel qui est en réalité plus une abstraction DAO mal nommée. Un référentiel qui reste fidèle au modèle aurait une seule méthode Get(id) et peut-être une méthode Find(ISpecification). Les modifications apportées aux entités seraient automatiquement suivies par une unité de travail (UnitOfWork), et le référentiel enregistrerait les entités avec l'unité de travail lorsqu'elles sont chargées. Donc, non, un Référentiel devrait être différent d'un DAO.

0 votes

Merci pour l'explication, j'ai un doute, est-il possible d'avoir une interface de référentiel dans la couche domaine et d'implémenter cette interface de référentiel en utilisant des dao dans la couche infrastructure.

142voto

Stef Points 476

OK, je pense pouvoir mieux expliquer ce que j'ai mis dans les commentaires :). Donc, fondamentalement, vous pouvez voir les deux comme la même chose, bien que DAO soit un modèle plus flexible que Repository. Si vous voulez utiliser les deux, vous utiliserez le Repository dans vos DAO. Je vais expliquer chacun d'entre eux ci-dessous :

REPOSITORY :

C'est un dépôt d'un type spécifique d'objets - il vous permet de rechercher un type spécifique d'objets ainsi que de les stocker. En général, il ne traite qu'un seul type d'objets. Par exemple AppleRepository vous permettrait de faire AppleRepository.findAll(criteria) o AppleRepository.save(juicyApple) . Notez que le référentiel utilise les termes du modèle de domaine (et non ceux de la base de données - rien qui ne soit lié à la façon dont les données sont conservées quelque part).

Un référentiel stockera très probablement toutes les données dans la même table, alors que le modèle ne l'exige pas. Le fait qu'il ne gère qu'un seul type de données le rend logiquement connecté à une table principale (s'il est utilisé pour la persistance de la BD).

DAO - data access object (en d'autres termes, objet utilisé pour accéder aux données)

Un DAO est une classe qui localise des données pour vous (il s'agit principalement d'un finder, mais il est souvent utilisé pour stocker les données). Le modèle ne vous limite pas à stocker des données du même type, vous pouvez donc facilement avoir un DAO qui localise/stocke des objets liés.

Par exemple, vous pouvez facilement avoir un UserDao qui expose des méthodes telles que

Collection<Permission> findPermissionsForUser(String userId)
User findUser(String userId)
Collection<User> findUsersForPermission(Permission permission)

Tous ces éléments sont liés à l'utilisateur (et à la sécurité) et peuvent être spécifiés dans le même DAO. Ce n'est pas le cas pour Repository.

Enfin

Notez que les deux modèles ont la même signification (ils stockent des données et en abstraient l'accès, ils sont exprimés plus près du modèle du domaine et ne contiennent pratiquement aucune référence à la base de données), mais la façon dont ils sont utilisés peut être légèrement différente, DAO étant un peu plus flexible/générique, tandis que Repository est un peu plus spécifique et restrictif à un type seulement.

0 votes

Si je comprends bien, par exemple, j'ai quelque chose comme CarDescription qui a par exemple language_id comme clé étrangère - alors pour le récupérer, je devrais faire quelque chose comme ceci : CarRepository.getAll(new Criteria(carOwner.id, language.id)); ce qui me donnerait toutes les voitures d'une langue dans une langue spécifique - est-ce la bonne façon de faire ?

0 votes

@StefanFalk, jetez un coup d'oeil à Spring Data, il vous permet de faire des appels beaucoup plus jolis que cela. Par exemple, cela pourrait être écrit comme suit CarRepository.findByLanguageId(language.id) et vous n'avez même pas besoin d'écrire le code, vous définissez simplement l'interface avec une méthode portant ce nom et Spring Data se charge de construire l'implémentation de la classe par défaut pour vous. C'est assez intéressant ;)

0 votes

Ce site montre comment écrire des requêtes dans Spring Data, mais en aurais-je besoin si j'utilise Hibernate ? Ou dois-je simplement implémenter TodoReporitory dans une autre classe qui implémente ensuite ces méthodes comme MyRepository extends TodoRepository donde MyRepository utilise Hibernate pour la persistance. Il y a tellement d'informations disponibles que je commence à m'y perdre au milieu d'un projet où j'ai déjà une base de données plus importante et une communication entre le serveur et le client.

112voto

Nazar Merza Points 1106

Les modèles DAO et Repository sont des moyens d'implémenter la couche d'accès aux données (DAL). Commençons donc par la couche d'accès aux données.

Les applications orientées objet qui accèdent à une base de données, doivent avoir une certaine logique pour gérer l'accès à la base de données. Afin de garder le code propre et modulaire, il est recommandé d'isoler la logique d'accès à la base de données dans un module séparé. Dans l'architecture en couches, ce module est le DAL.

Jusqu'à présent, nous n'avons pas parlé d'une implémentation particulière : seulement d'un principe général qui consiste à placer la logique d'accès aux bases de données dans un module séparé.

Maintenant, comment pouvons-nous mettre en œuvre ce principe ? Eh bien, une façon connue de le mettre en œuvre, en particulier avec des frameworks comme Hibernate, est le modèle DAO.

Le modèle DAO est une façon de générer un DAL, où typiquement, chaque entité de domaine a son propre DAO. Par exemple, User y UserDao , Appointment y AppointmentDao etc. Un exemple de DAO avec Hibernate : http://gochev.blogspot.ca/2009/08/hibernate-generic-dao.html .

Alors qu'est-ce que le modèle de référentiel ? Comme DAO, le modèle Repository est aussi un moyen de réaliser DAL. Le point principal du modèle Repository est que, du point de vue du client/utilisateur, il doit ressembler ou se comporter comme une collection. Ce que l'on entend par se comporter comme une collection n'est pas qu'elle doit être instanciée comme Collection collection = new SomeCollection() . Au contraire, cela signifie qu'il doit supporter des opérations telles que l'ajout, la suppression, le contenu, etc. C'est l'essence même du modèle Repository.

Dans la pratique, par exemple dans le cas de l'utilisation d'Hibernate, le pattern Repository est réalisé avec DAO. C'est-à-dire qu'une instance de DAL peut être à la fois une instance du pattern DAO et du pattern Repository.

Le modèle de référentiel n'est pas nécessairement quelque chose que l'on construit au-dessus de DAO (comme certains peuvent le suggérer). Si les DAO sont conçus avec une interface qui supporte les opérations mentionnées ci-dessus, alors il s'agit d'une instance du modèle Repository. Pensez-y, si les DAO fournissent déjà un ensemble d'opérations de type collection, alors quel est le besoin d'une couche supplémentaire par-dessus ?

10 votes

"Si les DAO fournissent déjà un ensemble d'opérations de type collection, alors quel est le besoin d'une couche supplémentaire par-dessus ?". Supposons que vous modélisez une animalerie et que vous avez une table 'PetType' avec différents animaux et leurs attributs (nom : "Cat", type : "Mammal", etc.) référencée par une table 'Pet' des animaux domestiques concrets que vous avez dans la boutique (nom : "Katniss", race : "Calico", etc.). Si vous voulez ajouter un animal d'un type qui n'est pas déjà dans la base de données, vous pourriez utiliser un référentiel pour regrouper les deux appels DAO distincts (l'un pour créer le PetType et l'autre pour le Pet) en une seule méthode, évitant ainsi le couplage dans les DAOs

1 votes

Superbe explication, Monsieur !

97voto

rakehell404 Points 105

Franchement, cela ressemble à une distinction sémantique, pas à une distinction technique. L'expression Data Access Object ne fait pas du tout référence à une "base de données". Et, bien que vous puissiez le concevoir de manière à ce qu'il soit centré sur la base de données, je pense que la plupart des gens considéreraient qu'il s'agit d'un défaut de conception.

Le but du DAO est de cacher les détails de l'implémentation du mécanisme d'accès aux données. En quoi le modèle Repository est-il différent ? Pour autant que je sache, il ne l'est pas. Dire qu'un Repository est différents à un DAO parce que vous traitez/renvoyez une collection d'objets n'est pas correct ; les DAO peuvent également renvoyer des collections d'objets.

Tout ce que j'ai lu sur le modèle de référentiel semble reposer sur cette distinction : mauvaise conception de DAO contre bonne conception de DAO (aka modèle de référentiel).

10 votes

Oui, tout à fait d'accord, ils sont essentiellement les mêmes. DAO semble plus lié à la DB, mais ce n'est pas le cas. Comme le référentiel, c'est juste une abstraction utilisée pour cacher où et comment les données sont situées.

1 votes

+1 Pour cette déclaration. Franchement, cela ressemble à une distinction sémantique, pas à une distinction technique. L'expression Data Access Object ne fait pas du tout référence à une "base de données".

1 votes

La comparaison entre les référentiels et les collections ne porte pas sur le fait qu'ils traitent/renvoient des collections d'objets, mais sur le fait que les référentiels se comportent comme s'ils son eux-mêmes. Par exemple, en Java, cela signifie qu'un Repository n'a pas de méthode de mise à jour car lorsque vous modifiez un objet dans une collection, il est automatiquement mis à jour (parce que les collections Java ne stockent que des références à des objets).

18voto

Mohamed Abed Points 2951

Le référentiel est un terme plus abstrait orienté domaine qui fait partie du Domain Driven Design, il fait partie de la conception de votre domaine et d'un langage commun, le DAO est une abstraction technique pour la technologie d'accès aux données, le référentiel ne concerne que la gestion des données existantes et les usines de création de données.

Vérifiez ces liens :

http://warren.mayocchi.com/2006/07/27/repository-or-dao/ http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-repository.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X