... e non viceversa. Con questo intendo dire che il modello ad oggetti che utilizziamo non dovrebbe essere mai modellato, in nessuna delle sue parti, pensando al fatto che quello specifico modello ad oggetti dovrà essere mappato su di un modello relazionale.
Perchè dico questo? perchè spesso vedo, o semplicemente sento, che questo concetto viene in alcuni casi "dimenticato" a favore della semplicità (ma è poi vera questa semplicità o è solo apparente?) di implementazione della relazione tra i due mondi.
Ma andiamo con ordine, ieri "chiaccherando" di architettura con il collega Marco, sono stato simpaticamente tacciato di farmi un sacco si "segh* mentali" ed io candidamente ho riposto che se il mio lavoro potesse essere fatto di magagne architetturali e segh* mentali che devono portare ad una soluzione elegante, performante e di semplice utilizzo sarei felicissimo. Quando ci sono problemi tecnici da risolvere io sono effettivamente a mio agio e sotto pressione poi rendo anche parecchio.
Perchè sono stato additato come "puntiglioso"? perchè eravamo di fronte al classico problema di dover gestire il rapporto del nostro modello ad oggetti con il database nel momento in cui di mezzo c'è una relazione "molti a molti".
Facciamo un esempio, decisamente simile alla realtà dei fatti, immaginiamo di avere una rappresentazione in memoria di un albero con però ha la caratterisitca che questo albero oltre ad avere la classica relazione padre-figlio/i ha anche la possibilità di avere, come "figli" di un nodo, dei link ad altri nodi, potremmo paragonarli ai link che su filesystem metteremmo in una folder per puntare ad un'altra folder sempre su filesystem.
Il nostro modello è quindi così rappresentabile:
interface INode
{
INode Parent { get; }
String Name { get; set; }
INodeList Nodes { get; }
INodeList Links { get; }
}
interface ITree : INode
{
}
faccio notare come sia Nodes che Links abbiano lo stesso tipo di ritorno.
Questo modello, nello specifico la collection Links, è una classica relazione molti a molti che sul db possiamo rappresentare con una tabella di ponte: "NodesTable" <--> "Links" <--> "NodesTable", dove in Links abbiamo la PK della Source e la PK della Destination.
In molti casi lo sviluppatore si arrende e per rappresentare quella relazione modella il suo dominio come se lo trova sul db, quindi modella una entità INodeLink, con la relativa collection, ed espone quella, ma questa cosa anche se non necessariamente sbagliata secondo me è comunque una di quelle cose che potrebbero ricadere sotto il cappello del "code smell". Sia chiaro ci sono dei casi in cui questo modello ha decisamente senso, anche se anche qui ci sono soluzioni probabilmente più eleganti, pensiamo ad esempio alla relazione "Studenti <--> EsamiSostenuti <--> Esami" in cui abbiamo bisogno di aggiungere informazioni (metadati?) oltre alla semplice relazione.
Tutto questo per arrivare a fare una cosa che per lo sviluppatore è decisamente naturale, e cioè una cosa del tipo:
ITree sourceTree = null;
ITree destTree = null;
IServiceContainer sc = ServiceContainer.GetContainer();
using( ITreeDataProvider dp = sc.GetService<ITreeDataProvider>() )
{
sourceTree = dp.GetByKey( pk );
destTree = dp.GetByKey( pk );
}
INode sourceNode = sourceTree.Nodes[ 0 ];
INode destNode = destTree.Nodes[ 3 ];
sourceNode.Links.Add( destNode );
IChangeSet cSet = null;
using( IChangeTrackingService<ITree> ctSvc = sc.GetService<IChangeTrackingService<ITree>>() )
{
cSet = ctSvc.GetChangeSet( sourceTree );
}
using( IUnitOfWork uow = sc.GetService<IUnitOfWork>() )
{
uow.Append( cSet );
uow.Commit();
cSet.AcceptChanges();
}
il bello è che funziona pure... e vista l'architettura che abbiamo messo in piedi ci sono volute un paio d'ore (dalla stesura delle classi alla creazione delle tabelle/sp sul db) per introdurre il "concetto" nel nostro mondo.
Direi che anche oggi (o meglio stamattina dalle 4.30 alle 6.30) ci siamo guadagnati una parte della pagnotta, che abbiamo poi consumato con il consueto training fisico mattutino...
il mattino ha l'oro in bocca, il mattino ha l'oro in bocca, il mattino ha l'oro in bocca <cit.>, che debba comiciare a preoccuparmi?
Noooooo finchè non chiamo Andrea "Wendy" direi che non ci dovrebbero essere problemi :-D
Detto questo direi che è doveroso ricordare che se vi può interessare capire cosa c'è dietro quegli snippet di codice siete i benvenuti: "cercasi".
.m
Technorati Tags:
Architettura