Dopo il post di ieri (qui e qui) che faceva trapelare delle verità (sconvolgenti) su come il team di ADO.NET lavori in seno al progetto Entity Framework, stanotte ho letto questo post fiume di Matt Warren che fa capire come la strada presa dai progettisti di Linq 2 SQL sia stata ben diversa.
Si perchè di "due team diversi" stiamo parlando, e sul perchè abbiamo fatto le stesse cose, è fonte di discussioni filosofiche
[ a cui non crederò mai, ma questa è un altra storia...:-) ]
Veniamo al punto, questo è l'articolo (molto lungo) e metto l'attenzione al solito su alcuni punti:
LINQ to SQL is not just another LINQ provider. It has been from the beginning and still is the quintessential LINQ provider, shaping and being shaped by the same process that designed LINQ.
Opps...mi pare di averlo detto proprio a cena alla fine della prima sera con i ragazzi dei community days. Linq to SQL è il provider probabilmente più importante tra tutti i vari "linq flavor" ed è quello che ha sicuramente influenzato l'attuale disegno di Linq stesso.
LINQ is the recognition that objects (in our case CLR objects) are the core of everything you as a programmer do.
Parafrasando Andrea in un thread di ieri su un forum...
posso quotare la frase di Matt con un FONT altezza 84???
So for LINQ the high-order bit was not only making it possible to represent your domain information as objects but making the ability to manipulate those objects in domain specific ways first class
Finalmente delle parole sensate.
The important area of manipulation was the query and since query was pervasive throughout most other highly used domains it was obvious that query would need to become first class in the language and runtime.
Concordo. Il problema di *tutti* gli attuali O/RM è che l'interrogazione viene fatta tramite una miriade di API che mettono l'*oggetto* al centro dell'attenzione (vedi HQL) ma che sono poco integrate sui nostri IDE e linguaggi di programmazione.
LINQ to SQL’s primary job became the representation of the relational database data as objects and the translation of language integrated queries into remotely executing database queries.
Of course, since this coincides with the territory of ORM systems it should come as no surprise that LINQ to SQL has taken on that role as well, enabling a degree of mapping between the objects you use in the language and the shape of data in the relational database.
Perfetto! ai community io mi ero "autosmentito" proprio per il fatto che avevo riconosciuto in Linq 2 SQL tutte le componenti necessarie per considerarlo un O/RM a tutti gli effetti. Probabilmente non con tutte le feature di O/RM più storici e affermati (vedi lo stesso NHIbernate, ma anche Genome), ma pur sempre un O/RM by design. Con quell'arma fondamentale in più: "Linq" come strumento di espressione delle query a livello di business.
One of our primary tenets from the get-go was to enable plain-old-CLR-object (POCO) development.
We received enough feedback from earlier prototypes of ObjectSpaces to know that customers really cared about this and what specifically about it mattered the most to them.
Ma così si fa!! non si comprano i libri di DDD per capire che c'è necessità di Persistence Ignorance (uno dei principi chiave della DDD).
Si prende invece gente con un po di esperienza nel campo degli ORM e si ascoltano i feedback degli utenti.
Il discorso dei POCO lo riassumo in breve (abbiamo fregato il concetto ai POJO ma poco cambia):
Sono classi che:
1. non hanno necessità di ereditare da nessuna classe base
2. che non devono implementare nessun tipo di interfaccia
3. che non hanno bisogno di factory per essere costruite
4. che non hanno bisogno di costruttori specifici per essere costruite
5. che non hanno nessuna logica interna per la persistenza
Linq 2 SQL rispetta tutte queste caratteristiche. Ne ho parlato sempre alla sessione, l'unica presenza "nuova" è data dagli oggetti EntitySet e EntityRef che volendo possono essere nascosti rispetto all'interfaccia pubblica, ma che comunque possono essere considerati trasversali al concetto di persistenza, ed infatti ecco qui la corretta spiegazione:
EntityRef and EntitySet don’t actually tie back to the database or LINQ to SQL infrastructure at all. They were designed to be completely free of any such entanglements, having no references back to contexts, connections or other abstractions...You are free to reuse them for whatever diabolical purpose you can imagine.
Bellissimo il "diabolic", e capisco anche la scelta progettuale. Nelle mie architetture cerco di astratte il concetto di Proxy rispetto all'ORM usato,e adesso posso contare su un oggetto che mi fa questo. Mica male. NHibernate dal canto suo, per far lavorare alcune delle sue feature, necessità di entità con tutti i metodi marcati come virtual o la necessità di implementare una interfaccia per ogni tipo, come pure la definizione di interfacce per le collezioni per favorire l'inversione di controllo.
Bene, si può ragionare su quale sia la scelta migliore o no, ma si vede che cmq in ogni caso, qualche "pezzo" di pulizia del modello di dominio, in un modo o nell'altro bisogna cederlo. Ci può stare. Linq to SQL ha un piccolo livello di invasività, ma può essere mascherata e ciò non lo rende impraticabile.
LINQ allowed us to finish the puzzle that was started when database access was first mashed together with object oriented languages. LINQ to SQL became the embodiment of this object-to-database solution, focusing the design on query, domain objects and the integration of both into the language and runtime
Questa si che è una chiusura. Bravi Ragazzi.
Certo, a questo punto mi mordo le dita perchè se Linq to SQL avesse avuto due feature in più (giusto DUE!), sarebbe stato un competitor tremendamente più forte, nel campo degli O/RM. Evabbè...non si può avere tutto.