web-dev-qa-db-fra.com

Modèle de référentiel vs DAL

S'agit-il de la même chose? Je viens de terminer de regarder Tutoriel Storefront de Rob Connery et ils semblent être des techniques similaires. Je veux dire, lorsque j'implémente un objet DAL, j'ai les méthodes GetStuff, Add/Delete etc et j'écris toujours l'interface en premier pour pouvoir changer de db plus tard.

Suis-je confus?

91
Mike

Vous n'êtes certainement pas celui qui confond les choses. :-)

Je pense que la réponse à la question dépend de la quantité de puriste que vous voulez être.

Si vous voulez un point de vue DDD strict, cela vous mènera sur un chemin. Si vous regardez le référentiel comme un modèle qui nous a aidés à normaliser l'interface de la couche qui sépare les services et la base de données, il vous en descendra un autre.

De mon point de vue, le référentiel n'est qu'une couche d'accès aux données clairement spécifiée, c'est-à-dire une manière standardisée de mettre en œuvre votre couche d'accès aux données. Il existe des différences entre les différentes implémentations de référentiel, mais le concept est le même.

Certaines personnes imposeront davantage de contraintes DDD au référentiel tandis que d'autres utiliseront le référentiel comme médiateur pratique entre la base de données et la couche de service. Un référentiel comme un DAL isole la couche de service des spécificités d'accès aux données.

Un problème d'implémentation qui semble les rendre différents est qu'un référentiel est souvent créé avec des méthodes qui prennent une spécification. Le référentiel renverra des données qui satisfont à cette spécification. La plupart des DAL traditionnels que j'ai vus, auront un plus grand ensemble de méthodes où la méthode prendra n'importe quel nombre de paramètres. Bien que cela puisse sembler une petite différence, c'est un gros problème lorsque vous entrez dans les domaines de Linq et Expressions. Notre interface de référentiel par défaut ressemble à ceci:

public interface IRepository : IDisposable
{
    T[] GetAll<T>();
    T[] GetAll<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors);
    void Delete<T>(T entity);
    void Add<T>(T entity);
    int SaveChanges();
    DbTransaction BeginTransaction();
}

S'agit-il d'un DAL ou d'un référentiel? Dans ce cas, je suppose que ce sont les deux.

Kim

86
Kim Major

Un référentiel est un modèle qui peut être appliqué de différentes manières, tandis que la couche d'accès aux données a une responsabilité très claire: le DAL doit savoir comment se connecter à votre stockage de données pour effectuer des opérations CRUD.

Un référentiel peut être un DAL, mais il peut également se placer devant le DAL et servir de pont entre la couche d'objet métier et la couche de données. La mise en œuvre utilisée variera d'un projet à l'autre.

41
Jeromy Irvine

Une grande différence est qu'un DAO est un moyen générique de gérer la persistance pour toute entité de votre domaine. En revanche, un référentiel ne traite que des racines agrégées.

23
pondermatic

Je cherchais une réponse à une question similaire et je suis d'accord avec les deux réponses les mieux classées. En essayant de clarifier cela par moi-même, j'ai trouvé que si les spécifications, qui vont de pair avec le modèle de référentiel, sont implémentées en tant que membres de première classe du modèle de domaine, alors je peux

  • réutilisation Définitions de spécifications avec différents paramètres,
  • manipuler les paramètres des instances de spécification existantes (par exemple pour se spécialiser),
  • combinez-les ,
  • exécuter la logique métier sur eux sans jamais avoir à accéder à la base de données,
  • et, bien sûr, test unitaire indépendamment des implémentations réelles du référentiel.

Je peux même aller si loin et déclarer que sauf le modèle de référentiel est utilisé avec le modèle de spécification, ce n'est pas vraiment un "référentiel", mais un DAL. Un exemple artificiel en pseudo-code:

specification100 = new AccountHasMoreOrdersThan(100)
specification200 = new AccountHasMoreOrdersThan(200)

assert that specification200.isSpecialCaseOf(specification100)

specificationAge = new AccountIsOlderThan('2000-01-01')

combinedSpec = new CompositeSpecification(
    SpecificationOperator.And, specification200, specificationAge)

for each account in Repository<Account>.GetAllSatisfying(combinedSpec)
    assert that account.Created < '2000-01-01'
    assert that account.Orders.Count > 200

Voir Essai de spécification de Fowler pour plus de détails (c'est sur cela que j'ai basé ce qui précède).

Un DAL aurait des méthodes spécialisées comme

IoCManager.InstanceFor<IAccountDAO>()
    .GetAccountsWithAtLeastOrdersAndCreatedBefore(200, '2000-01-01')

Vous pouvez voir comment cela peut devenir rapidement fastidieux, d'autant plus que vous devez définir chacune des interfaces DAL/DAO avec cette approche et implémentez la méthode de requête DAL.

Dans .NET, les requêtes LINQ peut peuvent être un moyen d'implémenter les spécifications, mais la combinaison des spécifications (expressions) peut ne pas être aussi fluide qu'avec une solution maison. Quelques idées pour cela sont décrites dans this SO Question .

12
Thomas Jung

Mon opinion personnelle est qu'il s'agit de cartographie, voir: http://www.martinfowler.com/eaaCatalog/repository.html . Ainsi, la sortie/entrée du référentiel sont des objets de domaine, qui sur le DAL pourraient être n'importe quoi. Pour moi, c'est un ajout/restriction important, car vous pouvez ajouter une implémentation de référentiel pour une base de données/service/autre avec une disposition différente, et vous avez un endroit clair pour vous concentrer sur la cartographie. Si vous ne deviez pas utiliser cette restriction et avoir le mappage ailleurs, avoir différentes manières de représenter les données peut avoir un impact sur le code à des endroits où il ne devrait pas être modifié.

2
eglasius

C'est une question d'interprétation et de contexte. Ils peuvent être très similaires, voire très différents, mais tant que la solution fait l'affaire, qu'est-ce qu'un nom!

1
c00ke

L'avantage de l'utilisation du modèle de référentiel est de simuler votre couche d'accès aux données, afin que vous puissiez tester le code de votre couche métier sans appeler de code DAL. Il y a d'autres gros avantages mais cela me semble très vital.

1
Shailesh

Le référentiel est un modèle, c'est un moyen d'implémenter les choses de manière standardisée pour réutiliser le code comme nous le pouvons.

0
Xulfee

Dans le monde externe (c'est-à-dire le code client), le référentiel est le même que DAL, sauf:

(1) ses méthodes d'insertion/mise à jour/suppression sont limitées pour avoir l'objet conteneur de données comme paramètre.

(2) pour l'opération de lecture, il peut prendre des spécifications simples comme un DAL (par exemple GetByPK) ou des spécifications avancées.

En interne, il fonctionne avec une couche Data Mapper (par exemple le contexte de structure d'entité, etc.) pour effectuer l'opération CRUD réelle.

Ce que le modèle de référentiel ne signifie pas: -

De plus, j'ai vu que les gens étaient souvent confus d'avoir une méthode Save distincte en tant qu'implémentation d'exemple de modèle de référentiel en plus des méthodes Insert/Update/Delete qui validaient toutes les modifications en mémoire effectuées par les méthodes insert/update/delete dans la base de données. Nous pouvons avoir une méthode Save définitivement dans un référentiel, mais ce n'est pas la responsabilité du référentiel d'isoler les méthodes CUD en mémoire (Créer, Mettre à jour, Supprimer) et de persistance (qui effectue l'opération d'écriture/modification réelle dans la base de données), mais le responsabilité du modèle d'unité de travail.

J'espère que cela t'aides!

0
Ashraf Alam

Donc, dans la plupart des cas (simples), DAO est une implémentation de Repository?

D'après ce que je comprends, il semble que DAO traite précisément de l'accès à la base de données (CRUD - Pas de sélection cependant?!) Tandis que le référentiel vous permet d'abstraire l'accès complet aux données, pouvant être une façade pour plusieurs DAO (peut-être différentes sources de données).

Suis-je sur la bonne voie?

0
Mike

D'après ce que je comprends, ils peuvent signifier essentiellement la même chose - mais la dénomination varie en fonction du contexte.

Par exemple, vous pourriez avoir une classe Dal/Dao qui implémente une interface IRepository.

Dal/Dao est un terme de couche de données; les niveaux supérieurs de votre application pensent en termes de référentiels.

0
remotefacade