In questi giorni stavo seguendo un therad sul forum di GUISA, "Generic Special Case?", dove si parlava di provare a vedere se tecnicamente era possibile generalizzare uno special case e in particolare si è preso come esempio il tipo Unknown (di cui in questi giorni si è discusso un pò sui blogs e un pò nel forum, "uso dello special case unknown").
Sono abbastanza convinto - come ho detto - che giudico che il costruire castelli troppo alti intorno allo special case unknown sia rendere complesso quello che poi è un problema molto più semplice. Inoltre credo che per quanto riguarda l'introduzione/la costruzione di strutture vale la pena se ne facciamo reale uso, esempio abbiamo classi di utilità o controlli che sfruttano la generalizzazione di un concetto.
In alcune delle soluzioni proposte - seppure interessanti - lo special case relativo ad un certo tipo non estende il tipo stesso... e quindi dove finiscono i principi base del pattern Special Case?! Inoltre mi è quasi venuto il sospetto che si associ lo special case al solo "pattern" unknown... ma in realtà l'unknown è un "pattern" che si appoggia sullo special case ma non è l'unico special case.
Come credo si possa ridurre/semplificare la questione dello pattern unknown cercando in un qualche modo di generalizzare il problema? La tecnica che popongo è quella di usare una "Empty Interface", un'interfaccia senza membri ma che aiuti a identificare dei tipi. In questo modo possiamo costruire strutture di supporto generiche/globali...
class Person{}
interface IUnknownEntity{}
class UnknownPerson: Person, IUnknownEntity{}
stati class Helper{
public static bool IsUnknown(object o){
return o is IUnknownEntity;
}
}
Grazie all'uso dell'interfaccia credo si possa dire che la classe UnknownPerson risolve due "problemi": 1. risolve il problema della definizione della calsse Unknown per la classe Person (problema del disegno del modello applicativo); 2. risolve il problema della generalizzazione della definizione del concetto dell'Unknown da usare per la definizione di classi di supporto all'applicazione per funzionalità cross per tutte le entità.
Su MSDN troviamo questo articolo "Avoid empty interfaces", dove si consiglia di usare i custom attribute invece di interfacce vuote come marcatori; ma se si tratta di risolvere problemi a compile time - e non solo a runtime - la cosa è giudicata accettabile.
"If your design includes empty interfaces that types are expected to implement, you are probably using an interface as a marker, or a way of identifying a group of types. If this identification will occur at runtime, the correct way to accomplish this is to use a custom attribute. Use the presence or absence of the attribute, or the attribute's properties, to identify the target types. If the identification must occur at compile time, then using an empty interface is acceptable."
Come risposndo a MS? Preferisco risolve compilando l'istruzione "is" invece che intervenire a RunTime con l'uso di Reflection per "intercettare" gli attributi.
posted @ domenica 29 ottobre 2006 20:06