[English Version]
Leggendo il post di Giancalo "NHibernate: Session e Lazy Loading" mi sono ricordato che è da tempo che volevo bloggare come recentemente sto implementando il Lazy Load... è bene premettere che sebbene il post inizia con riferimento ad un post su NHibernate questo post non riguarda tale tecnologia ma riguarda una possibile tecnica di lazy load.
Partiamo dal primo mio concetto... come vedo/mi piace vedere la divisione tra i layer di una applicazione? Ogni layer può parlare solo con quello direttamente sotto di lui, tutti i layer conoscono il modello (le entità di business) e ovviamente per esigente tecniche (evitare referenza circolare) le entità di business non conoscono nessuno.
Come implementare un lazy load? Tempo fa intrapresi la discussione con Emanuele Del Bono con un interessante scambio di mail ... al tempo avevo la stessa idea di oggi sull'architettura - quella sopra descritta - ma risolvevo la cosa troppo macchinosamente... :( Alcuni risolvono la questione usando eventi che notificano l'esigenza delle entità di caricare proprietà ondemand... soluzione interessante ma non mi piace che l'entità sappia cosa è giusto caricare in modalità lazy e cosa no. La modalità di caricamento dei dati in fondo è - a mio avviso - una questione unicamente del DAL che sa meglio di chiunque altro cosa è conveniente relativamente alla base dati da lui gestita. Alla fine sono giunto alla consclusione che il polimorfismo è quello che fa al caso mio! :-D
Ecco qui a codice maccaronico quello che intendo tralasciando la questione di DAL astratto e DAL concreti di cui ho già espesso parere in "Archietture a plugIn, pensieri e considerazioni "...
[Assembly del Modello]
public class Person
{
private Guid code= Guid.Empty;
public virtual Guid Code
{
get{return code;}
set{code= value};
}
private string name = string.Empty;
public virtual string Name
{
get{return name;}
set{name = value};
}
private AddressCollection addresses = new AddressCollection ();
public virtual AddressCollection Addresses
{
get{return addresses ;}
set{addresses = value};
}
}
[Assembly di un DAL concreto]
class PersonDataProvider: IPersonDataProvider
{
public Person RetrievePersonByCode(Guid code)
{
//TODO: Preparo il command per estrarre dal database la Persona dato il codice.
IDataReader r = cmd.OpenReader();
if(r.Read())
{
Person person = new InnerPerson();
person.Code = (Guid)r["Code"];
person.Name = (String)r["Name"];
person.Addresses = null;
return person;
}else{
return new UnknownPerson();
}
}
class InnerPerson: Person
{
public override AddressCollection Addresses
{
get
{
if(base.Addresses == null)
{
//TODO: Preparo il comando per estrarre gli indirizzi per questa persona...
//TODO: Creo e popolo la collezione degli indirizzi (base.Addresses).
}
retturn base.Addresses;
}
set{base.Addresses = value;}
}
}
}
Polimorfismo: "la possibilità che una classe derivata ridefinisca i metodi e le proprietà dei suoi antenati rende possibile che gli oggetti appartententi ad una classe che ha delle sottoclassi rispondano diversamente alle stesse istruzioni. I metodi che vengono ridefiniti in una sottoclasse sono detti "polimorfi", in quanto lo stesso metodo si comporta diversamente a seconda del tipo di oggetto su cui è invocato"
"You state that you want a function to have the flexibility of late-binding properties using the keyword virtual. You don’t need to understand the mechanics of virtual to use it, but without it you can’t do object-oriented programming in C++. In C++, you must remember to add the virtual keyword because, by default, member functions are not dynamically bound. Virtual functions allow you to express the differences in behavior of classes in the same family. Those differences are what cause polymorphic behavior." (Bruce Eckel, Thinking in C++)
Technorati Tags:
Data DesignPattern Architetture
posted @ giovedì 5 gennaio 2006 19:34