Come sempre il NG è fonte di ispirazione... L'argomento DataSet vs Entity è ormai trito e ritrito, ma per chi è agli inizi non è banale. Prima di tutto voglio chiarire, secondo me, in quale scenario i DataSet possono essere utili: i DataSet sono la rappresentazione in memory del DB, quindi "sono dei rettangoli" (cit.
Andrea) e sono stati creati per rappresentare fedelmente i DB (non uno storage qualsiasi), pertanto sono presenti righe, colonne, relation etc..., ma niente di più. Se è necessario fare un travaso di dati, eventualmente elaborarli e poi aggiornare il DB, possono essere utili, non avrebbe molto senso perdere tempo a scrivere un Domain Model e rispettivo Data Layer per fare un'operazione di questo tipo. I DataSet possono anche essere utili in "applicazioni che non vedranno mai la versione 2.0" (cit.
Raffaele), anche se in questo caso il beneficio mi sembra minimo, considerando che l'unica cosa che si evita è di scrivere il DAL, perchè anche le
classi hanno un designer!
In tutti gli altri casi è necessario scrivere un
Domain Model (le entity e le loro relazioni), un
Data Access Layer (possibilmente astratto, vedi
NSK), un
Service Layer che contiene l'application logic (regole di business, validazione, security etc...) ed eventualmente il Presentation (in varie tecnologie: Windows, Web, Web +
Silverlight, Mobile). Un'applicazione monolitica è difficilmente aggiornabile e non risponde all'esigenze del mercato, che richiede reattività e versatilità.
Domain Model

Creare un Domain Model con classi e custom collection produce dei grossi vantaggi rispetto ai DataSet:
- è possibile sfruttare pienamente il paradigma
OOP
- le classi rappresentano
data & behavior, i DataSet molto difficilmente
- le performance migliorano notevolmente (si possono creare dei
DTO ad-hoc, per ogni
servizio esposto dall'application server)
- il Data Access Layer può creare delle classi proxy (NHibernate lo può fare anche
dinamicamente) che consentono di caricare i dati in modo lazy, cioè solo quando necessario (e.g. nel "get" di una property pesante, come un'immagine, non alla crezione dell'oggetto)
Layering

E' necessario stratificare correttamente i blocchi funzionali dell'applicazione, e renderli indipendenti fra di loro, perchè l'applicazione sia versatile e si riescano a riflettere i cambiamenti alle logiche in modo tempestivo, e per rendere scalabile quanti più blocchi possibili, in modo che all'aumentare delle richieste sia possibile migliorare le performance aggiungendo risorse.
In questo scenario ad esempio il Data Access Layer, il livello che si occupa della persistenza dei dati (su DB, file-system o servizi esterni), può essere sostituito a seconda dello storage sul quale si vuole andare, senza modificare nessun altro blocco dell'applicazione, che non conosce assolutamente i dettagli implementativi, ma solo i contratti che ha a disposizione per persistere i dati.
Altra cosa importante è non implementare tutta la logica applicativa nel Business Layer perchè è possibile che più applicazioni lavorino sugli stessi dati, ma con logiche differenti, oppure che anche la stessa applicazione lavori sullo stesso dato ma con vincoli e logiche differenti a seconda del contesto.
Esempio.
Un portale consente la registrazione degli utenti in due modalità:
- light: viene richiesto solamente l'indirizzo email per l'invio della news letter
- full: sono richiesti dati di fatturazione, per l'acquisto di beni/servizi
La classe Person viene utilizzata in entrambi i contesti ma ovviamente le logiche di validazione sono differenti. Se queste fossero cablate in un ipotetico metodo IsValid all'interno della classe stessa, sarebbe difficile (non impossibile) soddisfare.
Matteo Migliore.