2010-05-06 15 views
8

Dans le contexte de l'application n-tier, existe-t-il une différence entre ce que vous considérez comme vos classes d'accès aux données et vos référentiels?Repository vs Data Access

J'ai tendance à penser oui mais je voulais juste voir quelle autre pensée. Je pense que le travail du référentiel consiste simplement à contenir et exécuter la requête brute elle-même, où la classe d'accès aux données créerait le contexte, exécuter le référentiel (passer dans le contexte), gérer le mappage du modèle de données au modèle de domaine et retournez le résultat ...

Qu'en pensez-vous? Également, voyez-vous cela changer dans un scénario Linq to XML (en supposant que vous changiez le contexte pour le XDocument concerné)?

Vive Anthony

MISE À JOUR:

Ceci est la façon dont je l'aurais généralement mis en œuvre des choses auparavant:

public class TermBl : ITermBl 
{ 
    public IEnumerable<ITerm> GetAll(IListParameter criteria) 
    { 
     //Any pre business logic 

     var dataLayer = this.CreateDataLayer(); 
     var result = dataLayer.GetAll(criteria); 

     //Any post business logic 

     return result; 
    } 

    ... Other methods 
} 

public class TermDa : ITermDa 
{ 
    public IEnumerable<ITerm> GetAll(IListParameter criteria) 
    { 
     //Linq query 
     var dataResult = ....ToList() 

     var mappedResult = this.FromDataToDomain(dataResult); 
     //Note the mapping isn't done in this object, the actual 
     // mapping is handled by a separate component 

     return mappedResult; 
    } 

    ... Other methods 
} 

Voyez-vous des problèmes inhérents ici avec le modèle en général .. En ce qui concerne le dépôt où j'ai pensé à utiliser le, il est au lieu d'avoir la requête directement dans le GetAll de TermDa.

méthode que je changerais à ressembler à quelque chose plus comme ceci:

public class TermDa : ITermDa 
{ 
    public IEnumerable<ITerm> GetAll(IListParameter criteria) 
    { 
     var repository = this.CreateRepository(); 
     var dataResult = repository.GetAll(..., criteria).ToList(); 

     var mappedResult = this.FromDataToDomain(dataResult); 

     return mappedResult; 
    } 

    ... Other methods 
} 

public class TermRepository : ITermRepository 
{ 
    public IQueryable<ITerm> GetAll(IMyContext context, IListParameter criteria) 
    { 
     //Linq query 
     return ...; 
    } 

    ... Other queries 
} 

Est-ce que vous les gars comment voir travailler ou pas vraiment ... Avec ou sans le dépôt que je vois soit de ce qui précède la protection totale de la couche d'affaires de connaître tout ce qui concerne les méthodes d'accès aux données/la technologie utilisée ...

Répondre

9

Oui, il y a une différence majeure.

  • A DAL (comme une table de données Gateway) est un concept de base de données . Il est chargé d'émettre des requêtes à la base de données et de renvoyer des ensembles d'enregistrements.

  • Un dépôt est un domaine concept de. Il est responsable de l'acceptation demandes structurées et retourne objets fortement typés.

Très différent en pratique.


Mise à jour:

La question semble refléter une quantité importante de confusion, mais laissez-moi de clarifier un exemple de code. Voici un design que vous pourriez utiliser si vous n'utilisiez aucun ORM et que vous faisiez tout votre propre mapping à la place.Rien de tout cela est un code de qualité de production, il est juste à des fins éducatives:

d'accès aux données:

public interface IOrderData 
{ 
    IDataReader GetOrder(int orderID); 
} 

public interface IOrderDetailData 
{ 
    IDataReader GetOrderDetails(int orderID); 
} 

public interface IProductData 
{ 
    IDataReader GetProduct(int productID); 
} 

Domaine:

public class Order 
{ 
    public int ID { get; set; } 
    public DateTime Date { get; set; } 
    public OrderStatus Status { get; set; } 
    // etc. 
    public IList<OrderDetail> Details { get; set; } 
} 

public class OrderDetail 
{ 
    public int ID { get; set; } 
    public Product Product { get; set; } 
    public int Quantity { get; set; } 
} 

Cartographie:

public interface IDataMapper 
{ 
    Order MapOrder(IDataRecord record); 
    OrderDetail MapOrderDetail(IDataRecord record); 
    Product MapProduct(IDataRecord record); 
} 

Repository:

public interface IOrderRepository 
{ 
    Order GetOrder(int orderID); 
} 

public class OrderRepository 
{ 
    // These get initialized in the constructor 
    private readonly IOrderData orderData; 
    private readonly IOrderDetailData orderDetailData; 
    private readonly IProductData productData; 
    private readonly IDataMapper mapper; 

    public Order GetOrder(int orderID) 
    { 
     Order order; 
     using (IDataReader orderReader = orderData.GetOrder(orderID)) 
     { 
      if (!orderReader.Read()) 
       return null; 
      order = mapper.MapOrder(orderReader); 
     } 
     using (IDataReader detailReader = 
      orderDetailData.GetOrderDetails(orderID)) 
     { 
      while (detailReader.Read()) 
      { 
       OrderDetail detail = mapper.MapOrderDetail(detailReader); 
       detail.Product = ...; // Omitted for brevity, more reading/mapping 
       order.Details.Add(detail); 
      } 
     } 
     return order; 
    } 
} 

Est-ce maintenant plus de sens faire? Le DAL traite des données. Le référentiel concret peut encapsuler des classes d'accès aux données, mais le référentiel abstrait (son interface publique) ne gère que les classes de domaine. Encore une fois, je rappellerai aux lecteurs que ce n'est même pas proche du code de qualité de production, et que la plupart des applications utilisent aujourd'hui un ORM ou au moins une meilleure forme de mappage automatique. Ceci est à titre illustratif seulement.

+0

Alors voyez-vous un objet DAL utilisant un objet de référentiel? c'est-à-dire quand vous dites émettre des requêtes, je pense qu'il le ferait en appelant le référentiel ... presque comme le référentiel est un proxy pour procs stockés dans une base de données, sauf que les requêtes sont dans le référentiel ... –

+0

@vdh_ant: Non , une DAL n'a généralement aucune connaissance du modèle de domaine. L'implémentation d'un dépôt (pas son interface/type de base) pourrait utiliser le DAL, bien que la plupart des nouveaux projets n'aient même pas de DAL, tout est encapsulé dans un ORM.Le référentiel n'est pas ** un proxy aux objets de la base de données, vous avez mal compris de quoi il s'agit. – Aaronaught

+0

@Aaronaught: mettre le référentiel de côté pendant une seconde, quand vous dites "DAL n'a généralement aucune connaissance du modèle de domaine" cela va à l'encontre de ce que j'ai vu autour de moi ... penser d'un point de vue interface/contrat le DAL doit retourner quelque chose et j'ai principalement vu que quelque chose devait être le modèle du domaine. Quand je pense à quoi d'autre cela pourrait être, ce ne pourrait être que les modèles de données ... J'aurais pensé que c'était mauvais pour plusieurs raisons. Principalement parce que votre couche logique métier est maintenant couplée à un modèle de données spécifique à différentes technologies ... –

1

Vous semblez avoir une bonne idée dessus. Les "classes d'accès aux données" peuvent prendre beaucoup de formes différentes. C'est une sorte de classe qui a quelque chose à voir avec l'accès aux données. Votre référentiel est (A) un modèle de gestion de la persistance de vos données et (B) un emplacement dans votre schéma d'accès aux données (si vous implémentez le référentiel).

Un défi dans votre stratégie d'accès aux données est de fournir une flexibilité et une capacité réutilisable en même temps. Tout en étant efficace. Tout en travaillant en même temps avec votre logique d'entreprise, étant découplé mais aussi cohésive. Rusé. Référentiel est un modèle qui prétend aider avec tout cet équilibre. Votre code de traduction de la base de données (ou autre) vers/à partir des classes d'entités réside en un seul endroit, pour chaque entité. Vos «classes d'accès aux données» peuvent être constituées de vos classes de référentiel, ainsi que des classes qui gèrent réellement le travail SQL. Vous ne devriez certainement pas faire tout le sql cruft dans chacune de vos classes de dépôt. Exemple: vous pouvez commencer par utiliser une réflexion inefficace mais facile pour remplir vos objets d'entité, sans travailler dans vos classes de référentiel; plus tard, vous pouvez le rendre plus efficace pour les entités de haut volume, mais cela est complètement caché à d'autres parties de votre système. Et plus tard, vous déplacez la configuration vers XML, mais le reste de votre système n'a aucune idée de ce changement.

LINQ-to-sql et Entity framework tirent vraiment parti du modèle de référentiel, car ce que les classes du référentiel renvoient est en réalité une propriété de cette entité. Les classes métier peuvent appliquer des critères supplémentaires, et ces critères parviennent réellement au SQL, tout en fournissant une encapsulation complète à partir de la persistance des données. C'est vraiment cool.

+0

@Patrick Karcher: Vous voyez donc un objet DAL utilisant un référentiel ou vous voyez les dépôts comme un type différent de DAL ou qu'il n'y a pas de chevauchement ... c'est à dire que vous avez choisi d'utiliser un DAL ou un référentiel de votre couche métier ... –

+0

@vdh_ant Si vous avez un dépôt, vous pouvez dire qu'il est moitié dans votre DAL et moitié au-dessus. Mieux vaut le dire * liens * votre DAL avec tout ce qui précède. Ou, vous pourriez le voir comme votre référentiel * utilise * le DAL (complètement caché de toute votre interface utilisateur et couche de gestion) pour persister vos données. ** Ou **, vous pourriez avoir vos sqlconnections et tel ** dans ** vos classes de dépôt. Si tel est le cas, vous pouvez pointer vers vos classes de référentiel et les appeler le DAL; probablement un "DAL +", car non seulement il obtient/met vos données, mais il l'enveloppe particulièrement bien pour le reste de votre application. ** DAL est un terme vague! ** –

+0

@vdh_ant Ce que vous essayez de maîtriser est (je pense) la partie la plus difficile de faire une bonne application, * flexible *. Si vous ne savez pas exactement ce que les gens veulent dire par DAL, et comment configurer le "back end" de votre application, vous êtes en bonne compagnie! Les gens très intelligents, qui ont payé beaucoup d'argent, pensent en ce moment: «Maintenant, comment diable puis-je configurer mon accès aux données pour ce projet? En réalisant que vous ne connaissez pas la meilleure façon, et en demandant ce que vous demandez, vous êtes en avance sur beaucoup de gens qui * croient * qu'ils ont ce truc tout compris. –