Iniziamo con una piccola nota polemica, concedetemelo :-)
un dev è un professionista come tanti altri, medici o idraulici ad esempio, e quello che mi aspetto da un medico o da un idraulico è che abbia una buona conoscenza, ma soprattutto confidenza, dei suoi strumenti… quindi come è normale che un idraulico sappia cosa è un sifone mi aspetto che un dev sappia cosa è metticiunpoquellochevuoi di Visual Studio; non mi aspetto che lo sappia usare ma mi aspetto che la curiosità l’abbia spinto almeno a dargli un’occhiata.
Purtroppo sempre più spesso consto che questo è molto lontano dalla realtà di tutti i giorni. Che opinione si farebbe un paziente di un dentista che litiga con uno specillo?… e non ditemi che non sapete cosa sia uno specillo… no non è uno specchietto :-)
Detto questo vediamo di affrontare un altro nodo molto importante nell’organizzazione di un qualsiasi progetto software. Nel mio piccolo tendo ad essere un po’ allergico al Class View, non chiedetemi perchè semplicemente faccio fatica ad usarlo e preferisco di gran lunga interfacciarmi con il Solution Explorer.
Se confrontate le due immagini non è che ci sia molta differenza quindi direi che la scelta è puramente soggettiva, ma tutto depende… da che depende…
Si ma il Class View cerca…
vero, questo è interessante, dal Class View è possibile cercare un membro per nome ma la domanda a questo punto è: se un progetto è ben organizzato a cosa mi serve cercare?
Notate il solution explorer qui a sinistra? che differenze ha con il class view sopra? pressochè nessuna… perchè l’orgnizzazione dei progetti è parallela e sincrona, ad esempio, all’organizzazione dei namespace.
Che senso ha in un’organizzazione di questo tipo cercare? potrebbe avere senso pensare che un qualcosa del tipo: Topics.Radical.Model.NHibernate.NHibernateDataContext stia in un posto diverso dal progetto Radical.Model.NHibernate?
Espandendo uno dei progetti ci rendiamo immediatamente conto della cosa:
Ad ognuno il suo spazio
Supponiamo adesso di dover distribuire nella solution i seguenti elementi:
interface IEngine
{
Boolean IsActive { get; }
}
interface IEngine<T> : IEngine
{
EngineOperationResult OperateOn( T data );
}
enum EngineOperationResult
{
Success,
Aborted,
Denied
}
tralasciate il design che è tutto tranne che importante adesso e nello specifico probabilmente è pure errato ;-) ma non ci interessa quello… come distribuireste gli elementi di cui sopra nella solution? così:
Con dentro il file Engine.cs tutto il necessario? o così:
lascio a voi la scelta, ma io preferisco la seconda soluzione, ci metto 12 secondi, netti, in più ma ho un colpo d’occhio molto più efficace, molto, ma molto :-)
Il vostro obiettivo è la produttività e la produttività non si misura di certo con il tempo che il compilatore impiega ad analizzare 100.000 files piuttosto che 1 con 10.000.000 di righe, chi se ne frega, intanto che lui compila io bevo il caffè :-)
La produttività secondo me si misura in dimistichezza, facilità di manutenzione, facilità di passaggio di consegne e condivisione del lavoro, facilità di capire al volo dove devo mettere mano per fare una certa cosa, nel primo esempio (Engine.cs) se devo mettere mano all’enumerazione devo per forza usare il Class View, nel secondo no… e se poriettate questo su una solution media:
con qualcosa come 5000 file, di soli sorgenti, è evidente che se le cose non sono maniacalmente organizzate come si deve è più il tempo che passate a cercare che quello che passate a lavorare :-) non parliamo poi del fatto che magari dovete riprendere in mano lavori di qualche mese fa… se l’organizzazione è fallace: panico.
ma… le Partial Class?
Diciamocelo subito, secondo me puzzano :-)
Se non ricordo male le partial class sono state introdotte per poter tenere separato il codice generato dal designer di Windows Forms dal nostro codice, da li le possibilità sono cresciute e lo stesso meccanismo viene sfruttato da Wpf per la separazione tra il codebehind e lo xaml:
Le possiamo usare per organizzare meglio le nostre classi? certo che si, secondo me però prima di farlo val la pena di fare qualche considerazione:
- non è che stiamo utilizzando le Partial Class come utilizzeremmo le #region?
- non è che le stiamo facendo diventare il tappeto sotto cui nascondere la fuffa?
Secondo me il rischio c’è e io tendo a sfruttare queste sensazioni per far emergere potenziali problemi di design: ho una semplice regola se il codice della roba che sto scrivendo non ci sta tutto sullo schermo, e la scroll bar te lo fa capire molto bene, allora forse è il caso di fare un po’ di refactoring e non di fuffizzare il tutto in una Partial Class.
Ovviamente, come per tutte le regole, non è un dogma e va valutato di caso in caso: ad esempio i controller di MVC e i ViewModel di M-V-VM tipicamente, in quanto accentratori, sono anche un collo di bottiglia per l’organizzazione del codice perchè da li ci passa un intero UseCase, o addirittura più di uno…
.m