Data Access Layer 101

Forse ha ragione David: la mia risposta al post di Giulio (per quanto sintetica e quindi non esaustiva) non è proprio da buttar via. Per dovere di cronaca, la riporto qui.

[QUOTE]

>Ho una pagina aspx che viene interrogata per ottenere dei dati presenti in
>un DB (SQL Server). Il DB che ho (è solo per testare il tutto, ma anche
>quello di produzione non sarà molto più complesso) ha un unica tabella
>"Partecipante" (che indica tutti i partecipanti ad una manifestazione) con
>4 colonne: ID numerico (PK), cognome, nome, età. Ho pensato di modellizzare
>questa entità con un oggetto Partecipante che espone i valori delle quattro
>colonne come 4 proprietà. La mia idea è quella di ritornare alla pagina
>aspx un array Partecipante[] da cui poi questa estrae le info necessarie.
>La mia domanda è: come posso strutturare l'object model (se di object model
>si può parlare) del mio DAL (fisicamente implementato da una dll sviluppata
>a parte)? Pensavo ad un oggetto-singleto cui fare la richiesta di
>estrazione dei dati. Come potri chiamarlo? DBPartecipanti? Ve lo chiedo
>perchè visto che la libreria la utilizzerà una terza parte vorrei che anche
>i nomi fossero i più esplicativi possibile.
Giulio, direi che si potrebbe parlarne per taaaanto tempo Provo a darti la "big picture": in un mondo perfetto lo schema dati dell'applicazione è proprio l'object model che stai realizzando,  e *non* lo schema del db. L'object model può essere modellato ispirandosi al pattern "Domain Model" (http://www.martinfowler.com/eaaCatalog/domainModel.html). Secondo la formulazione "accademica" il DM contiene "...both data and behaviour..." quindi, strettamente parlando, potrebbe contenere anche la logica di persistenza (e robetta varia, come una implementazione di ActiveRecord), cioè esporre direttamente i tipici metodi CRUD.
Poichè DM "lavora" bene con "Service Layer" (http://www.martinfowler.com/eaaCatalog/serviceLayer.html), io preferisco considerare la persistenza un "servizio" e portarlo quindi fuori dal DM, lasciandovi solo la parte di behaviour considerabile "business". In pratica, cerco di rendere il mio DM quanto più "persistence ignorant" possibile. A questo punto, mi ritovo quindi con delle CRUD "business" che sanno ricevere ed "emettere" istanze del DomainModel applicandovi validazioni business e sapendo comunicare col DAL. In uno scenario semplice, la GUI insiste direttamente su queste CRUD per richiedere i servizi di persistenza. A questo punto, si tratta di decidere come queste CRUD comunichino col DAL.
Per implementare il DAL, io tipicamente mi baso su una struttura "Separated Interface" (http://www.martinfowler.com/eaaCatalog/separatedInterface.html) e "Abstract Factory" (http://www.dofactory.com/Patterns/PatternAbstract.aspx): in pratica, modello un DAL astratto in un assembly che verrà implementato da classi che risiedono in assembly differenti, e predispongo una factory nel DAL astratto che conosca il modo di reperire istanze del DAL concreto, e fornirle alle CRUD di business, che quindi non dipendono da uno specifico DAL concreto (che a questo punto è un reale Plugin).
In una ottica idiomatica, ti consiglio di non "passare" tra i layer degli array, ma di usare dei contenitori + evoluti. Evita di usare List<T> nelle API pubbliche (argomenti/valori di ritorno), poichè violeresti (http://blogs.msdn.com/kcwalina/archive/2005/09/26/474010.aspx) le Design Guidelines di MS (http://blogs.msdn.com/kcwalina/archive/2004/09/28/235232.aspx). Se vuoi definire dei tipi, usa Collection<T> come tipo base, altrimenti usa IList<T> (chiuso, ovviamente, sulle entity del tuo DM) nelle API pubbliche quando specifichi il tipo del contenitore.
Nei casi più esigenti, implemento una UnitOfWork (http://www.martinfowler.com/eaaCatalog/unitOfWork.html) che mi permette di creare contesti transazionali e ridurre il numero di roundtrip verso il db, eventualmente incapsulando nella UoW una IdentityMap (http://www.martinfowler.com/eaaCatalog/identityMap.html) per poter gestire una cache degli oggetti già generati. In questi casi, la GUI dialoga con la UoW. Se vuoi esagerare, puoi modellare UoW e IdentityMap come tipi astratti e permetterne implementazioni concrete differenti, rendendole delle Strategy (http://www.dofactory.com/Patterns/PatternStrategy.aspx). Quest'ultima scelta architetturale può risultare determinante se, per esempio, vuoi condividere DM e ServiceLayer tra una gui windows ed una web, dovendo basarti su differenti implementazioni del concetto di "sessione applicativa".
Troppa carne al fuoco? Vuoi una scorciatoia? Te ne suggerisco 2:
1) Vieni al workshop "Architecture Days" (http://www.ugidotnet.org/workshops/workshops_detail.aspx?ID=9ed3a5e7-a69c-4258-af7b-6ec3a8bcd025) organizzato da UGIdotNET presso Microsoft, perchè le sessioni " Life between the Domain Model and the Service Layer" e " Designing the Data Access Layer" parlano proprio di questi argomenti, presentando  uno scenario reale (con codice "live" e diagrammi UML del caso) e arrivando anche ad ipotizzare una soluzione basata su ORM
2) Se non puoi venire al workshop, scaricati l'applicazione che useremo come demo (si chiama NSK, la trovi qui: http://download.manageddesigns.it/nsk.aspx): è open source sotto licenza CPL, quindi puoi farne + o - ciò che vuoi. Tieni conto che la versione *attualmente* online non include ancora le feature che stiamo implementando per il workshop (ma è già un valido punto di partenza). Ovviamente, quando saremo pronti aggiorneremo anche la versione online

[END QUOTE]

Technorati tags: ,

posted @ Thursday, September 14, 2006 3:21 PM

Print

Comments on this entry:

# re: Data Access Layer 101

Left by David at 9/14/2006 3:35 PM
Gravatar
:-)
Comments have been closed on this topic.
«January»
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678