Alkampfer's Place

Il blog di Gian Maria Ricci
posts - 601, comments - 1063, trackbacks - 88

My Links

News

Gian Maria Ricci
Mvp Logo
CCSVI in Multiple Sclerosis

English Blog

Tag Cloud

Article Categories

Archives

Post Categories

Image Galleries

I miei siti

Siti utili

Preoccuparsi di POCO

Ho appena letto un paio di post, uno di Andrea ed uno di Raf, sul domain model e sulla effettiva necessità di un dominio non solo "persistence ignorant" ma infrastructure ignorant. Decisamente poter creare un dominio infrastructure ignorant è una sfida interessante, e non posso che dire di essere daccordo con Andrea. D'altra parte come Raf fa notare, pensare di usare proxy potrebbe essere veramente dannoso per le prestazioni.

Personalmente non vorrei preoccuparmi a priori delle prestazioni, a parte il "premature optimization is the root of all evil", preferisco avere una architettura più manutenibile, e tenere sotto controllo le prestazioni durante lo sviluppo per capire se le soluzioni adottate siano in linea con i requisiti. La generazione di proxy a runtime può essere interessante (ci ho lavorato e la reflection.emit è decisamente divertente), ma a mio avviso non è adatta per questo genere di cose, si è vero, posso generare un proxy che supporti INotify... e quello che mi pare, ma poi è una classe che a design time non esiste,  non posso interagirci, etc etc.

Un approccio decisamente migliore è la generazione del codice design time, un po come il dataset Strongly typed. In questo modo ad esempio si potrebbe scrivere un generatore di DTO a partire dagli oggetti di dominio. L'approccio dei DTO è infatti quello che preferisco, anche perchè è possibile in questo modo ridurre i dati da trasmettere. Se ho un oggetto con 10 proprietà e mi serve una lista di tali oggetti da mostrare su una griglia che binda solo 3 proprietà su 10, avere un DTO specializzato allo scopo è sicuramente la cosa migliore.

Il problema dei Dto è naturalmente che: se li gestisci a mano, puoi farlo per un dominio di poche entità, altrimenti diventi matto, se usi un generatore, questo deve essere il più possibile automatizzato. A suo tempo pensai ad esempio ad usare codesmith, ma c'è bisogno di qualche cosa di più efficiente. La cosa migliore sarebbe avere un designer simile a quello delle classi o dei dataset strongly typed, potere fare drag and drop di classi, decidere quali proprietà spostare e generare tutto il codice a design time, magari utilizzando anche delle partial property per potersi intrufolare in mezzo al codice generato se possibile. Il problema maggiore di un approccio fortemente DTO oriented è che, come dice raf

Il costo di creazione e manutenzione dei proxy e del codice che serve a fare quelle stesse cose (ma dall'esterno dell'entity) non è poco: maggiore complessità e ciclo di vita più lungo del software

Però in certi casi sono cose che tolleriamo senza problemi, il lazy load NHibernate lo fa con Castle.DynamicProxy (Nhibernate 2.0 dovrebbe essere portato a DynamicProxy2) ed è una cosa che non ha mai sollevato troppe obiezioni. D'altra parte ci fidiamo del fatto che il generatore di codice sia corretto, per cui l'unica manutenzione è al massimo quella di mantenere i file di mapping o qualsiasi artefatto sia stato creato per stabilire come il codice debba essere generato.

Il problema di fondo è che raggiungere la completa ignoranza dell'infrastruttura è sicuramente utopico e forse anche troppo radicale, quello che vorrei è solamente poter limitare al minimo questa intrusione. NHibernate riesce a fare persistenza richiedendo poche specifiche alle nostre classi (membri virtuali per i proxy, un costrutture di default, ..), per cui è sicuramente possibile fare librerie di infrastruttura poco intrusive ;). Mi piacerebbe che quando qualcuno progetta infrastrutture cercasse di realizzarle nel modo meno intrusivo per le entità di dominio, se poi questo non è possibile bene, ma almeno provare.

Il rischio è che ci si trovi ad avere la classe X che implementa 10 interfacce solo per il piacere di essere usata da EntityFramework, Reporting Services, Crap Library, bla bla.

alk.

Print | posted on giovedì 31 luglio 2008 14.45 |

Feedback

Gravatar

# re: Preoccuparsi di POCO

Avresti dovuto intitolarlo "Preoccuparsi _per_ POCO" :)
Alcune riflessioni, perché nel mio post non ho parlato solo di performance e voglio ribadire che le performance a volte le paghi care.
http://blogs.ugidotnet.org/raffaele/archive/2008/06/20/93106.aspx
L'ho toccato con mano in un progetto dove ho trovato fatta una architettura pensata senza cura per le performance e ormai non resta che riscrivere.

1. ho dei seri dubbi sulla usabilità del proxy sul DM. Generare (in qualsiasi modo tu lo faccia) un proxy che rivesta totalmente l'object model non è così banale e vorrei vedere il risultato su DM di una certa grandezza.
Per usabilità intendo la navigazione da codice, il riferimento alla root del DM, la gestione eventi, etc. etc. Prova a wrappare il DM di Word ...
2. per quanto buono sia il tool di generazione di proxy, avrai sempre delle casistiche che non calzano a pennello e ti rimarrebbe una buona parte di codice da scrivere nelle partial class, naturalmente oltre al mapping..... paghi tu o il cliente?
E il mapping non devi certo farlo con gli attributi altrimenti il POCO non c'è più.
3. Se ti accorgi che le performance non vanno quando hai finito l'architettura, sei fritto.
4. I DTO sono belli quando il DM è piccolo. Quando è grosso ti trovi il DM, il DM proxato, e magari anche le entity create da WCF da "colmare" nelle partial classes. E la manutenzione?

A questo punto chiediamoci se il vero target è una soluzione *didattica* (che coccia con i tempi e soldi del cliente) per avere il POCO a tutti i costi o non è meglio porsi il problema dal punto di vista del costo della manutenzione del codice (aka ciclo di vita del software) e prendere quella direzione.
31/07/2008 19.45 | Raffaele Rialdi
Gravatar

# re: Preoccuparsi di POCO

Completamente daccordo per le performance, è chiaro che se la soluzione architetturale non tiene comunque conto dell'aspetto performance rischi di riscrivere il tutto.
Per quanto riguarda il discorso dei proxy sicuramente non possono risolvere tutto, non penso sia possibile wrappare il DM di word, ma per applicativi più piccoli magari è fattibile.

Il problema reale è che se io debbo implementare una serie di interfacce, Es. INotifyPropertyChanged, da qualche parte il codice debbo pur metterlo. Se non usiamo i DTO, non usiamo proxy etc, allora tutto questo codice infrastrutturale deve da qualche parte risiedere, ed è meno bello che risieda nel DM. Se parli invece di IEditableObject allora è un discorso differente, perchè è una interfaccia mooolto più delicata, li bisogna intervenire a mano.

cmq con l'avvento di entityFramework e simili penso che in futuro questi argomenti avranno molto più spazio di discussione. Organizziamo una cena sull'argomento cosi ne parliamo a quattrocchi :D :D

alk.
01/08/2008 11.09 | Gian Maria
Gravatar

# re: Preoccuparsi di POCO

Ma è tutta la stessa zuppa...
- Il "meno bello" deve avere una spiegazione convincente per il cliente altrimenti non ha senso. Tra l'altro non implementare INotifyxxx nella entity introduce delle complessità in modo ingiustificato.
- Se ammetti IEditableObject allora ritorniamo al discorso di "elencare" le interfacce/attributi che sono ammessi e quelli che non lo sono. Ma automaticamente il puro "POCO" non c'è più, punto.
- Tiro in gioco anche WCF. DataContract e DataMember hanno senso se sono applicati su *alcuni* campi del DM.
Se il DM è solo fatto di POCO rinuncia anche a questi e automaticamente devi crearti un DM parallelo (ovviamente più piccolo) a costi decisamente eccessivi per la manutenzione.
DataContract e DataMember sono stati pensati per creare entity differenti in modo automatico ... cambia il nome della classe, dei membri, etc. e mi sembra da pazzi rinunciarci (oltre, nuovamente, alle performance perse per creare e distruggere il doppio degli oggetti)

Per la cena ... quando vuoi :)
01/08/2008 11.41 | Raffaele Rialdi
Gravatar

# re: Preoccuparsi di POCO

Infatti POCO a tutti i costi non è sicuramente il must, l'esempio di DataContract e DataMember è calzante e non ha molto senso fare un DM parallelo solo per mettere questi attributi.
In generale ho lavorato solo su domain model non grandi e quindi ho sempre usato i DTO per comunicare fuori dai servizi e quindi gli attributi di WCF li ho messi li, ma non troverei problemi nel metterli anche nelle classi del dm.
Quello che mi piacerebbe è cercare di "limitare" queste intrusioni infrastrutturali nei miei oggetti di dominio, ovvero non voglio POCO ad ogni costo, ma vorrei il più POCO possibile senza naturalmente dovere fare MOLTO SFORZO.

Il sunto di tutto è che a mio avviso, chi realizza librerie infrasrtutturali a grande diffusione (vedi EF), dovrebbe porsi il problema di essere il meno intrusivo possibile nelle classi di dominio, almeno come linea generale di progetto, se poi non è possibile ok, ma almeno averci pensato.

alk.


01/08/2008 14.17 | Gian Maria
Gravatar

# re: Preoccuparsi di POCO

Ah, dimenticavo, per la cena se capitassi mai dalle tue parti mi faccio sicuramente sentire :), se invece per qualche astrusa ragione passassi tu per le marche allora fatti sentire che ci facciamo una scorpacciata di cinghiale (sempre che a te piaccia :D)

alk.
01/08/2008 14.18 | Gian Maria
Gravatar

# re: Preoccuparsi di POCO

Ah perfetto ... così siamo daccordo.
Limitare l'intrusione nel DM è certamente una cosa da perseguire il più possibile. Ma niente martellate sui piedi *solo* perché "è bello" e se il suo costo ha un impatto su performance o ciclo di vita del software.
Quanto a EF hanno preso una bella cantonata sulla persistence ignorance, non c'è dubbio. D'altra parte il team di ado.net è platealmente "DB centrico" e quindi lo svirgolone è dovuto a questo.

Per l'incontro ci puoi contare. Attendo di sentirti se passi di qui e mi farò sentire se mi capita di venire dalle tue parti.
Ciao:)
01/08/2008 15.15 | Raffaele Rialdi
Comments have been closed on this topic.

Powered by: