2010-05-06 11 views
8

Nel contesto dell'applicazione n-tier, c'è una differenza tra ciò che considerereste le vostre classi di accesso ai dati e i vostri repository?Repository vs Data Access

Tendo a pensare sì ma volevo solo vedere quale altro pensiero. Il mio pensiero è che il lavoro del repository è solo per contenere ed eseguire la query raw stessa, dove come la classe di accesso ai dati creerebbe il contesto, eseguire il repository (passando nel contesto), gestire il mapping del modello di dati al modello di dominio e restituisci il risultato ...

Cosa ne pensate? Vedete anche questo cambiamento in uno scenario da Linq a XML (assumendo che si cambi il contesto per il relativo XDocument)?

Saluti Anthony

UPDATE:

Questo è il modo in cui avrei tipicamente implementato cose in precedenza:

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 
} 

Vede qualche problemi inerenti qui con il modello in generale ..

Per quanto riguarda il repository in cui ho pensato di utilizzarlo è invece di avere la query direttamente nel GetAll di TermDa Metodo vorrei cambiare farlo sembrare qualcosa di più simile a questo:

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 
} 

È così che ragazzi vederlo lavorare o no davvero ... Con o senza il repository che vedo uno di quanto sopra totalmente protezione dello strato di business da sapere tutto sui metodi di accesso ai dati/tecnologia utilizzata ...

risposta

9

Sì, c'è una grande differenza.

  • Un DAL (come ad esempio un gateway dati Tabella) è un concettodatabase. È responsabile per l'emissione di query nel database e la restituzione dei set di record.

  • Un repository è un concettodominio. È responsabile dell'accettazione delle richieste strutturate e della restituzione degli oggetti con caratteri corretti.

Molto diverso nella pratica.


Aggiornamento:

La domanda sembra riflettere una notevole quantità di confusione, in modo da farmi provare a chiarire con un esempio di codice. Ecco un disegno che potresti usare se non stavi usando un ORM e invece stavi facendo tutto il tuo mapping.Niente di tutto questo è il codice di produzione di qualità, è solo per scopi didattici:

accesso ai dati:

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

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

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

Domain:

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; } 
} 

Mapping:

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; 
    } 
} 

È questo rendendo più senso ora? Il DAL si occupa di dati. Il repository concreto può incapsulare classi di accesso ai dati, ma il repository astratto (la sua interfaccia pubblica) tratta solo le classi di dominio.

Ancora una volta mi limiterò a ricordare ai lettori che questo non è nemmeno vicino al codice di qualità di produzione e che oggi la maggior parte delle app utilizza un ORM o almeno una forma migliore di mappatura automatica. Questo è solo a scopo illustrativo.

+0

Quindi si vede un oggetto DAL che utilizza un oggetto repository? per esempio quando dici di emettere query, penso che lo farebbe chiamando il repository ... quasi come se il repository fosse un proxy per i proc memorizzati in un database, eccetto che le query sono nel repository ... –

+0

@vdh_ant: No , un DAL in genere non ha alcuna conoscenza del modello di dominio. L'implementazione di un repository (non la sua interfaccia/tipo di base) potrebbe utilizzare il DAL, anche se la maggior parte dei nuovi progetti oggi non ha nemmeno un DAL, è tutto incapsulato in un ORM.Il repository è ** non ** un proxy per gli oggetti del database, hai frainteso quello che è. – Aaronaught

+0

@Aaronaught: mettere da parte il repository per un secondo, quando dici "DAL in genere non ha alcuna conoscenza del modello di dominio" questo va contro ciò che ho visto in giro per il luogo ... pensando da una prospettiva interfaccia/contratto il DAL deve restituire qualcosa e ho visto soprattutto che qualcosa deve essere il modello di dominio. Quando penso a cos'altro potrebbe essere, potrebbero essere solo i modelli di dati ... Avrei pensato che questo fosse negativo per diverse ragioni. Soprattutto perché il tuo livello di business logic è ora abbinato a un modello di dati che è specifico per diverse tecnologie ... –

1

Sembra che tu abbia una buona idea. "Le classi di accesso ai dati" possono assumere molte forme diverse. È una sorta di classe che ha qualcosa a che fare con l'accesso ai dati. Il tuo Repository è (A) un modello per la gestione della persistenza dei dati e (B) un posto all'interno del tuo schema di accesso ai dati (se stai implementando il repository).

Una sfida nella strategia di accesso ai dati offre allo stesso tempo flessibilità e capacità riutilizzabili. Mentre allo stesso tempo è efficiente. Mentre allo stesso tempo lavorate con la vostra logica aziendale, essendo disaccoppiati ma anche essendo coesivo. Difficile.

Il deposito è uno schema che si propone di aiutare con tutto questo equilibrio. Il codice per la traduzione del db (o di qualsiasi altra cosa) da/verso le classi di entità risiede in un posto, per ciascuna entità. Le tue "Classi di accesso ai dati" potrebbero consistere nelle tue classi di repository e in quelle che effettivamente gestiscono il lavoro di sql. Certamente non dovresti fare tutto il sql cruft all'interno di ciascuna delle tue classi di repository.

Esempio: è possibile iniziare a utilizzare una riflessione inefficiente ma facile per riempire gli oggetti di entità, facendo quasi nessun lavoro nelle classi del repository; in seguito è possibile renderlo più efficiente per le entità ad alto volume, ma questo è completamente nascosto da altre parti del sistema. E in seguito si sposta qualche configurazione in XML, ma il resto del sistema non ha idea di questo cambiamento.

LINQ-to-sql e Entity framework sfruttano realmente il pattern di repository, perché ciò che restituiscono le classi di repository è in realtà un IQuerable di quell'entità. Le classi di business possono applicare criteri aggiuntivi e tali criteri lo rendono effettivamente al sql, pur continuando a fornire un incapsulamento completo dalla persistenza dei dati. È davvero fantastico.

+0

@Patrick Karcher: Così vedi un oggetto DAL che usa un repository o vedi i repository come un tipo diverso di DAL o che non c'è sovrapposizione ... cioè hai scelto di usare un DAL o un repository dal tuo livello aziendale ... –

+0

@vdh_ant Se si dispone di un repository, si potrebbe dire che è metà nel tuo DAL e metà sopra di esso. Meglio dirlo * collega * il tuo DAL con tutto quello sopra. Oppure, potresti vederlo come il tuo repository * usa * il DAL (completamente nascosto da tutta la tua interfaccia utente e dal tuo livello aziendale) per mantenere i tuoi dati. ** Oppure **, potresti avere le tue sqlconnections e tali ** in ** le tue classi di repository. In questo caso, puoi indicare le classi del tuo repository e chiamarle DAL; probabilmente un "DAL +", dal momento che non solo prende/mette i tuoi dati ma li avvolge particolarmente bene per il resto della tua app. ** DAL è un termine vago! ** –

+0

@vdh_ant Quello che stai cercando di ottenere è un aspetto (penso) la parte più difficile di fare una buona, * flessibile * app. Se sei confuso su cosa significhi esattamente la gente per DAL e su come impostare al meglio il "back-end" della tua app, sei in buona compagnia! Persone molto intelligenti, pagate un sacco di soldi, stanno pensando in questo momento, "ora, come diavolo faccio a impostare il mio accesso ai dati per * questo * progetto ...". Comprendendo che non conosci il modo migliore e chiedendo che cosa stai chiedendo, sei davanti a molte persone che * credono * che abbiano capito tutto questo. –

Problemi correlati