Wednesday, November 25, 2009

Fantastico!

throw new ServiceException( "Error sending e-mail, but e-mail sent successfully" );
e pure affascinante :-)
.m

Tuesday, November 24, 2009

Un doveroso grazie :-/

…a quel simpaticone, sinonomo di strunz, che in metropolitana ha cercato di estrarmi 2 costole, dalla loro sede naturale, salendo sul treno… mentre io scendevo…
Tutto quello che si è limitato a fare è stato “salutarmi” con aria sconsolata da dentro la carrozza senza neanche pensare di scendere, per fortuna che un disponibilissimo signore marocchino (e sottolineo marocchino) si è premurato di capire se da “per terra” dove stavo riuscivo ancora a respirare… shukran.
Al simpaticone direi che… meglio che non mi pronunci :-)
.m

Sviluppare per Windows Mobile su una macchina x64…

…è praticamente impossibile, mettevi l’anima in pace :-) ma non tutto è perso, altrimenti che scriverei a fare?
Il problema di fondo è che per sviluppare in maniera decente per Windows Mobile avete 2 requisiti:
  • che l’emulatore sia in grado di connettersi alla rete e qui sorgono i primi problemi perchè l’emulatore usa il driver di rete di Virtual PC 2007 che purtroppo non convive felicemente con Windows Virtual PC su Wiundows 7;
  • che il Cellular Emulator faccia il suo fantastico sporco lavoro e qui proprio non c’è mezzo perchè il Cellular Emulator non parte neanche su una macchina x64…
VMware Workstation
il tentativo, riuscito, è stato quello di spostare l’ambiente di sviluppo in una macchina virtuale:
  • ho installato Windows 7 x86;
  • ho installato Visual Studio 2008 e tutto quello che serve per lo sviluppo mobile, SDK compreso;
  • ho installato, con successo e con sorpresa, Virtual PC 2007 Sp1 x86 dentro la macchina virtuale;
e il risultato è questo:
vm dove si vede l’emulatore connesso a internet con una “incoming call”.
.m

Monday, November 23, 2009

Design Time Data, reloaded.

Ne abbiamo parlato non poco sia io che Corrado e l’argomento è stato ripreso durante il corso su Wpf che abbiamo tenuto questa settimana, a proposito:
trovo che sia decisamente produttivo, in particolare per la platea, partecipare ad un corso dove la docenza è in pair, con 2 docenti, con un background tecnico paragonabile, ma con un background lavorativo diverso perchè porta un arricchimento non da poco.
…torniamo “in topic” che è meglio :-)
L’obiettivo è poter avere, in Blend, questo:
image
Quindi semplicemente una design time experience degna del suo nome. L’inghippo, nel mio caso, è che usando M-V-VM, seguendo l’approccio ViewModel first, il ViewModel è fatto più o meno così:
sealed class SubjectsListViewModel :
    ItemsListViewModel<ISubjectsListView, Subject, Subject, Subject>,
    ISubjectsListViewModel
{
    public SubjectsListViewModel( IDispatcher dispatcher, 
ISubjectsListView view,
IMessageBroker broker,
IDataContextFactory dataContextFactory,
ISubjectsManagementService subjectsService,
IUserInteractionService uiService ) : base( dispatcher, view, broker, SelectionType.Extended ) {

...
}
}
il tutto viene gestito dal fido Castle quindi quel costruttore per me è decisamente friction-less, in ottica design time data però quella cosa è decisamente scomoda principalmente per 2 motivi:
  1. la classe non è pubblica e lo xaml si lamenta se cercate di usarla;
  2. la classe non ha un costruttore pubblico di default senza parametri e questo la rende definitivamente inutilizzabile via xaml;
L’approccio che ho usato fino ad ora funziona senza nessun problema ma è dispendioso in termini di tempo di setup… e questo non è friction-less… allora il cervelletto ravana ravana e stamattina durante il solito viaggio sul lebbrosario di turno mi è venuta una malsana idea… mi sono detto:
  1. perchè non riprendi quello che hai lasciato in sospeso…?
  2. e lo adatti a questo scenario che è decisamente più semplice?
Detto fatto, una mezz’ora e il giochetto era up & runnin’:
<Window x:Class="SubjectsListViewDocument"
        xmlns:design="http://schemas.topics.it/wpf/subjects/design"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d design">

    <Window.Resources>
        <design:Sample x:Key="sample" />
    Window.Resources>

    <Grid d:DataContext="{StaticResource sample}">
quella classe “Sample” è così definita, scroccando un po’ di sintassi a Fluent NHibernate:
public class Sample : DesignTimeHost<ISubjectsListViewModel>
{
    public Sample()
    {
        this.Expose( o => o.Items )
            .WithValue( new EntityView<Subject>( new List<Subject>()
            {
                new Person(){ FirstName = "Mauro", LastName = "Servienti" },
                new Company(){ CompanyName = "topics.it" }
            } ) )
            .AsReadOnly();
    }
}
e quello che mi resta da fare è limitarmi a fare quello che farei di solito (funziona perfettamente anche nei vari “property editor” di Blend):
<ListView ItemsSource="{Binding Path=Items}"...
Ottenendo il risultato di cui sopra, comodo semplice e definibile addirittura in un assembly separato. Complicandomi la vita ho cercato di esporre come design time data un modello ben più complesso (un master detail con un grafo decisamente ostico) incappando nei “solitinon pochi problemi che però stavolta possono essere brillantemente risolti:
var address1 = MockRepository.GenerateStub<IAddressViewModel>();
address1.Street = "sample street 1";

var address2 = MockRepository.GenerateStub<IAddressViewModel>();
address2.Street = "sample street 2";

this.Expose( e => e.Addresses )
    .AsReadOnly()
    .WithValue( new EntityView<IAddressViewModel>( new List<IAddressViewModel>()
    {
        address1,
        address2
    } ) );
utilizzando un tool di mocking, del resto siamo a design time, e producendo di fatto qualcosa di editabile in maniera umana, molto umana:
image
Finalmente perchè prima quel coso era ridotto ad un groviglio inguardabile, e adesso posso farlo diventare quello che serve diventi.
Adesso la domanda potrebbe essere: ma visto che funziona anche con un tool di mocking perchè non usare solo quello?
Cerca le differenze… :-)
image image
La cosa interessante è che, per avere a design time quel comportamento, ci possiamo limitare solo ed esclusivamente a questo:
<design:Sample x:Key="sample" DesignTimeAreDisplayedDataStale="[False]/[True]" />
Nonostante quel “pannello di warning” sia così definito:
<Border Grid.Row="0"
        Background="#FFFFFB9C"
        Visibility="{Binding AreDisplayedDataStale, Converter={StaticResource boolVisConv}}"
        BorderBrush="#FFFFF630"
        BorderThickness="1"
Quella proprietà “DesignTimeAreDisplayedDataStale” non esiste sul modello, e quindi non esisterebbe per il tool di mocking, ma esiste per il DesignTimeHost che è anche in grado di notificarne il cambiamento:
public sealed class Sample : DesignTimeHost<ISubjectsListViewModel>
{
    public Sample()
    {
        this.Expose( o => o.Items )
            .WithValue( new EntityView<Subject>( new List<Subject>()
            {
                new Person(){ FirstName = "Mauro", LastName = "Servienti" },
                new Company(){ CompanyName = "topics.it" }
            } ) )
            .AsReadOnly();

        this.Expose( o => o.AreDisplayedDataStale )
.BoundTo( this, s => s.DesignTimeAreDisplayedDataStale )
.WithLiveValue( () => this.DesignTimeAreDisplayedDataStale ) .AsReadOnly(); } private Boolean _designTimeAreDisplayedDataStale = false; public Boolean DesignTimeAreDisplayedDataStale { get { return this._designTimeAreDisplayedDataStale; } set { if( value != this.DesignTimeAreDisplayedDataStale ) { this._designTimeAreDisplayedDataStale = value; this.OnPropertyChanged( e => e.AreDisplayedDataStale ); } } } }
Quindi:
  • la proprietà AreDisplayedDataStale, esposta dal modello, è registrata con un live value, un delegato, e non con un valore statico come le altre;
  • viene aggiunta una proprietà DesignTimeAreDisplayedDataStale che non esiste sul modello e che al momento della variazione notifica il suo cambiamento come una normalissima proprietà…;
  • …proprietà che il DesignTimeHost tiene monitorata (BoundTo()) e, al momento della variazione, notifica a sua volta la variazione della proprietà AreDisplayedDataStale
…a questo punto il buon Blend, che ha istanziato il nostro DesignTimeHost, reagisce alla notifica e viene a rileggersi il valore della proprietà che non esiste invocando di fatto il delegato che rappresenta il live-value… si lo so sembra cervellotico ma funziona che è un piacere. La cosa più bella è che questo mi permette anche di simulare lo stato di abilitazione / disabilitazione degli ICommand esposti dal ViewModel.
Concludendo…
Con pochissimo codice siamo in grado di dare a Blend un set di dati, da usare a Design Time, anche molto complesso permettendoci di avere una Design Time Experience veramente di qualità.
.m

Friday, November 20, 2009

Questa è proprio figosa… :-)

Tra le tante novità di Wpf 4.0, questa è proprio interessante:
http://blogs.msdn.com/llobo/archive/2009/11/20/xaml-2009-features-factorymethod-arguments.aspx
.m

Yes, we can :-)

Andata, bene direi :-)
Volevo ringraziare tutti i partecipanti per:
  • la partecipazione, che non è cosa proprio così scontata;
  • il coinvolgimento, cosa altrettanto non scontata;
  • i momenti over-learning tra aperitivi, pranzi e cene;
Grazie!
Abbiamo alcune cose da affinare ma mi sento di poter asserire che l’obiettivo è stato raggiunto e possiamo cominciare a darci dentro come si deve!
Arriviamo :-)
.m

Spreco e Disprezzo

C’è troppa gente che spreca quello che a me costa sacrificio (spesso parecchio sacrificio), e soprattutto che se glielo fai notare sembra quasi che ne vada orgogliosa… io lo percepisco come una forma di disprezzo.
.m

Non che qui non ci si debba lamentare…

Untitled Altrimenti mi dicono che sono talebano… :-)
.m

Thursday, November 19, 2009

Che roba…

image
…devo comperarlo, diamine mi danno la batteria :-)… sono dei grandi!
.m

Friday, November 13, 2009

“Missing in Action”

Silenzio…qualcuno si chiede, forse, che fine ho fatto. Sono partito un paio di settimane fa con una serie di buoni propositi e da una settimana a questa parte silenzio.
In realtà la congiuntura astrale che si sta verificando, evento dell’anno+RobertoInfortunato+Maiala+OgniTantoLavoroPureIo, rende questo periodo molto faticoso e qualcosa va necessariamente perso per strada...
Sta di fatto che nulla è perduto, anzi… ho una serie di post in canna non da ridere:
(In ordine casuale)
  • Open Session: How to…: breve analisi di come funziona, e ha funzionato una “OpenSession”;
  • A cosa serve una “grid” in Wpf?: un po’ di considerazioni sul perchè non sento la mancanza di una griglia in Wpf;
  • Architettura basata su M-V-VM: perchè?: un po’ di elucubrazioni su M-V-VM non dal punto di vista tecnico;
  • Per la serie viviamo felici con Visual Studio:
    • E se non c’è una dipendenza?: come far funzionare un mondo basato su IoC;
    • Debuggare quello che non abbiamo nella solution…: come rendere debuggabile un mondo basato su IoC e con delle dipendenze da toolkit esterni;
    • Deploy aspetti fondamentali: un po’ di considerazioni sui processi di deploy e gli staging;
    • Branch-per-Feature: esperienze con TFS;
  • Ran Toolkit: il toolkit che uso per UI Composition potrebbe essere catapultato nella giungla…;
  • Radical Framework: anche lui andrà live?
    • Memento: il servizio di change tracking: continuiamo la serie iniziata sul Memento;
    • IEntityView: IBindingListView to the max;
  • Sandcastle: come lo uso, come si configura, comsa mi/gli manca;
  • Testare i mapping di NHibenate: tutto bello ma i mapping sono un problema quando il database esiste già;
  • Ma mi “facci” il servizio: un po’ di elucubrazioni sull’abuso dell’approccio SOA;
Mi dovrete sopportare anche per molto tempo, molto :-)
.m

Thursday, November 12, 2009

Ma… Opera per Windows Mobile…

…fa veramente pietà
Complice la maiala, eppure io le indicazioni di Topo Gigio milionario le ho seguite tutte…, sono “costretto” a cavarmela con quel che c’è e stamattina stavo smanettando un po’ con la versione di Opera installata sul mio HTC Diamond. Devo dire che l’experience è semplicemente pietosa, la tastiera a video è inutilizzabile, fa quello che vuole lei, l’autocompletition degli url è autogestita nel senso che prende le sue decisioni in autonomia facendoti vedre quello che decide lei… non ho parole, eppure le alte cariche gli danno pure retta a questi qua… e non ditemi di comperare un melafonino, lo so che il browser è semplicemente fenomenale, ma non ha senso spendere quei soldi per usare il browser 2 volte all’anno.
.m

Thursday, November 5, 2009

[OT] Pensieri sparsi… “reloaded”

Sono a Torino e tipicamente quando sono in albergo mi capita di guardare la televisione, a casa non c’è.
  1. Qui c’è già stato lo switch-over: il digitale terrestre fa pietà, non tanto per i contenuti che facevano pietà prima e adesso sono solo aumentati, quindi peggio su peggio :-) ma piuttosto fa tecnologicamente pietà, mi metto nei panni di un utente, non tecnico, che prima aveva un televisore e adesso ha un televisore + un “coso” con a bordo del software che è fatto tipicamente con i piedi, il decoder che ho qui in albergo è pressochè inutilizzabile… crasha: cribbio ma come è possibile che un televisore (perchè quello è il percepito) crashi… è come se crashasse il frigorifero;
  2. Per ora ho cumulato circa 1h di “visione” e:
    1. L’abitudine che in molti hanno di parlare addosso agli altri per zittirli è veramente odiosa;
    2. non ho trovato nulla che richiedesse un QI superiore a –1;
    3. Guardando un telegiornale capisci molte cose, ma proprio tante;
    4. La trasmissione di Papi, su Italia 1, è decisamente inutile, se la levassero e facessero mezz’ora di fermo immagine saremmo tutti molti più felici ;-);
  3. La fretta è sempre una cattiva consigliera, vedi punto 1, e, prima o poi, ti si ritorcerà contro;
  4. Il sarcasmo gratuito e mal celato è un’altra cosa che mi da molto fastidio;
  5. La formazione è alla base del successo tanto quanto l’ignoranza della controparte (vedi sempre punto 1);
.m

Componente != Servizio

Stavo leggendo una interessante serie di post sull’integrazione tra Castle e WCF, illuminante e istruttiva per molti versi ma sinceramente faccio molta fatica a digerire questo mascheramento.
Credo che in generale ci sia un problema di fondo nella teminologia usata: quando si parla di IoC si usa indifferentemente componente o servizio. L’errore secondo me sta nell’utilizzare poi indifferentemente servizio quando questo viene inteso come componente e quando questo invece viene inteso come servizio nel senso SOA del temine, portando alla convinzione che siano concettualmente utilizzabili allo stesso modo.
Secondo me non c’è nulla di più sbagliato, ho la ferma convinzione che il codice debba esplicitare, e non nascondere, che si sta utilizzando un servizio nel senso SOA del temine perchè l’approccio da utilizzare e le problematiche da gestire e prendere in considerazione sono abissalmente diverse.
Secondo me è un grave errore pensare che la differenza tra n-layer e n-tier stia solo nel fatto che il boundary è diverso. Non è possibile pensare di scrivere uin’applicazione n-layer e migrarla a n-tier piazzando un po’ qua e un po’ la Wcf e una facility per Castle.
Pensate a questo scenario:
using( var dc = this.dataContextFactory.Create() )
{
    using( var tx = dc.BegingTransaction( IsolationLevel.Serializable ) )
    {
        dc.Insert( entity );
        dc.FlushChanges();

        tx.Commit();
    }
}
IDataContextFactory è un wrapper per la session factory di NHibernate, nulla di trascendentale, il codice esplicita molto bene quello che succede. La IDataContextFactory viene iniettata con Castle Windsor. Adesso immaginamo che:
  • Qualcuno scrive una nuova implementazione di IDataContextFactory e IDataContext che utilizzano Wcf;
  • Qualcuno modifica il file di configurazione di Castle per utilizzare la nuova implementazione e la WcfFacility;
  • Qualcuno configura Wcf per utilizzare Message Queue;
Il codice la sopra scala immediatamente verso una transazione distribuita senza che nessuno abbia chiesto nulla ma peggio del peggio quella transazione distribuita passa da una Message Queue Transazionale…
Cosa succede se il servizio Wcf è giù?
.m

Wednesday, November 4, 2009

Code Snippets

Parliamo un po’ di produttività… ma non tanto in termini di linee di codice scritte in una unità di tempo quanto piuttosto di come e quanto cali la nostra, la mia sicuramente, resa a causa della noia che scrivere codice sempre uguale produce…
Se usate Wpf (o in generale sviluppo di applicazione rich client) questo è un esempio di noia mortale:
private String _myValue = null;
public String MyValue
{
    get { return this._myValue; }
    set
    {
        if( value != this.MyValue )
        {
            this._myValue = value;
            this.OnPropertyChanged( () => this.MyValue );
        }
    }
}
il supporto per INotifyPropertyChanged è veramente tedioso da scrivere e ad esempio in un’applicazione Wpf basata su M-V-VM lo scrivere decinaia e decinaia di volte :-)
Code Snippets
Perchè quindi non farsi un Code Snippet? che scritta una cosa del genere:
image
esploda in questo?:
image
permettendoci di ridurre all’osso quello che dobbiamo scrivere.
How to…
Un Code Snippet è semplicemente un file xml con estensione “.snippet” che opportunamente piazzato viene egregiamente digerito da Visual Studio e dall’intellisense:
image
Il Code Snippet che produce quella proprietà è questo:
xml version="1.0" encoding="UTF-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Creates a Property with PropertyChanged Support using lambda expressions.Title>
      <Author>topics.itAuthor>
      <Description>Description>
      <Shortcut>ppclShortcut>
      <SnippetTypes>
        <SnippetType>ExpansionSnippetType>
      SnippetTypes>
    Header>
    <Snippet>
      <Declarations>
        <Literal Editable="true">
          <ID>PropertyNameID>
          <Default>PropertyNameDefault>
        Literal>
        <Literal Editable="true">
          <ID>PropertyFieldID>
          <Default>propertyFieldDefault>
        Literal>
        <Literal Editable="true">
          <ID>PropertySystemTypeID>
          <Default>System.ObjectDefault>
        Literal>
        <Literal Editable="true">
          <ID>PropertyDefaultValueID>
          <Default>nullDefault>
        Literal>
      Declarations>
      <Code Language="csharp">
        private $PropertySystemType$ _$PropertyField$ = $PropertyDefaultValue$;
public $PropertySystemType$ $PropertyName$
{
    get { return this._$PropertyField$; }
    set 
    {
        if( value != this.$PropertyName$ )
        {
            this._$PropertyField$ = value;
            this.OnPropertyChanged( () => this.$PropertyName$ );
        }
    }
}$end$]]>
      Code>
    Snippet>
  CodeSnippet>
CodeSnippets>
Le 2 cose degne di nota sono la sezione “Declarations”:
<Declarations>
  <Literal Editable="true">
    <ID>PropertyNameID>
    <Default>PropertyNameDefault>
  Literal>
Declarations>
che serve per aggiungere elementi editabili durante la fase di editing, appunto :-), dello snippet, usando il tabulatore sarà possibile “navigare” tra i vari elementi all’interno dell’editor, e la sezione “Code”:
<Code Language="csharp">
  private $PropertySystemType$ _$PropertyField$ = $PropertyDefaultValue$;
public $PropertySystemType$ $PropertyName$
{
    get { return this._$PropertyField$; }
    set 
    {
        if( value != this.$PropertyName$ )
        {
            this._$PropertyField$ = value;
            this.OnPropertyChanged( () => this.$PropertyName$ );
        }
    }
}$end$]]>
Code>
In cui inserire il blocco di codice che vogliamo snippettare :-)
Ci sono svariati tool per la gestione degli snippet ma secondo me l’unico che merita, oltre naturalmente ad un decente editor per file xml (ad esempio Visual Studio :-) ) è questo add-in del “compare” Alessandro… che è un bravo ragazzo nonstante il set di che ha sul blog sembri dire tutto il contrario :-P
Happy snippetting… ok, ok, scusate :-)
.m

Tuesday, November 3, 2009

Lo sapevo io…

IMAGE_031
…che se stamattina la stazione di Treviglio era crashata e continuava a fare boot a nastro la giornata ferroviaria sarebbe stata un delirio…
Esco dal cliente e punto a prendere il Milano-Brescia delle 18.00… magari… il mondo si è fermato ed entro in casa adesso… ben più di 2h per fare 31km.
.m

Outlook to the max

Fino ad un paio di anni fa avevo l’abitudine di categorizzare le mail utilizzando una pletora di subfolder della Inbox, il problema è che spesso questo le rende introvabili :-) perchè a distanza di tempo quando vi chiedete “dove ho messo quella roba” giustamente non vi ricordate più l’associazione mentale fatta al tempo e tipicamente passate un buon quarto d’ora a scartabellare tra le folder… oppure semplicemente avrebbe senso mettere la stessa mail in più subfolder.
Ho regalato troppi “quarto d’ora” :-)
Due anni fa circa, in una mattina a Barcellona, ero seduto di fianco a Davide Vernole e facendo il curioso noto che non ha subfolder ma ha semplicemente tutto spiattellato nella Inbox e mi spiega che usa le categorie per taggare la mail… figo :-)
…l’inghippo purtroppo è che chi ha pensato le categorie evidentemente non le ha mai usate perchè per taggare una singola mail perdete ben più di un quarto d’ora… :-/
Rules rulez
Ma anche qui piegare lo strumento è abbastanza facile:
image
Mi sono fatto una pletora di regole che fanno il 90% del lavoro, se non di più, lasciando a me l’onere di rifinirlo ove necessario. Queste regole fanno si che all’arrivo ogni mail venga automaticamente taggata:
image image
Il fatto che le regole siano client only è un non problema perchè Outlook le applica anche ai messaggi già letti, quindi se segno come già letto un messaggio da OWA o dal Device quando arriva in Outlook viene comunque processato e categorizzato.
Cerca che ti passa…
Ma poi come sfruttiamo questo tagging? Semplicemente si può cercare per categoria, ma la cosa che adoro sono le Search Folder che con un piccolo trick diventano veramente fantastiche:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Outlook\QueryBuilder]
(Funziona su tutte le versioni di Outlook, basta sostituire a 14.0 il vostro numero di versione)
Se provate a creare quella chiave di registro, senza metterci nulla basta che esista, e poi provate ad editare/creare una Search Folder… tada!:
image
Avete un potente sistema di filtro a vostra disposizione per fare query anche molto articolate.
Dimenticavo: prestazionalmente non cambia nulla avere tutto nella Inbox:
image
Questa è la dimenisione della mia Inbox attuale con i messaggi dall’inzio dell’anno, la ListView dei messaggi è virtualizzata quindi…
.m

Visual Studio Template

Nell’ottica di addomesticare lo strumento e non di piegare noi stessi ai limiti, o presunti tali, dello strumento stesso, ci sono una quantità notevole di piccole cose che possiamo fare per semplificarci la vita.
Faccio Unit Test e TDD, credo nella giusta misura, e uso con soddisfazione MSTest per tutta una serie di buone ragioni, ma se c’è una cosa che mi da veramente fastidio è questa:
image
Che cosa notate? mi sono limitato ad aggiungere ad un progetto di test un nuovo test, nulla di più, eppure:
  • Il codice del template è commentato… non serve, e per molti, me compreso, è pessima pratica commentare i test;
  • la scroll bar è lunga come la fame…;
  • C’è già scritto un sacco di codice;
Insomma non ho ancora fatto nulla e c’è un sacco di rumore di fondo, non va bene; questo è quello che vorrei:
image
sintetico ed essenziale, senza fronzoli e rumore di fondo.
Facciamolo!!
Credo non ci sia nulla di più facile, basta provare… con un progetto aperto provate a fare: File => Export Template e seguite il semplice wizard :-) poi andate a dare una sbirciatina nella cartella dei settings di Visual Studio, tipicamente: “User Profilo\Documents\Visual Studio 2008\My Exported Templates”… it’s a kind of magic, magic
.m

Monday, November 2, 2009

Un paio di settimane di “pomodori”

Sono un paio di settimane che sto seguendo la “ricetta” e ho notato che il fatto di averne parlato ha stuzzicato l’interesse.
Quoto Andrea Dottor:
Per quanto mi riguarda, non la conoscevo e ne sono rimasto da un lato affascinato, nel senso che, porsi degli obiettivi da 25 minuti non è affatto complesso, e rimanere concentrati per 25 minuti è una cosa fattibile…
L’esperienza di queste 2 settimane mi fa dire che:
  1. 25 minuti sono lunghissimi :-)
  2. Stare concentrati per 25 minuti su un obiettivo è impegnativo, devi imparare a gestirti: è fondamentale che l’ecosistema in cui sei calato ti sia amico:
    1. Sistema i tuoi strumenti in quell’ottica;
    2. Rendi partecipe chi ti circonda del perchè e del percome;
    3. Fatti rispettare da chi ti circonda;
Punto 2.1: ho fatto un’altro piccolo esperimento, riuscito alla perfezione, modificando nuovamente il comportamento del mio fido Outlook, da così:
image
a così:
image
Ho semplicemente tolto dai “Favorites” la Search Folder dei messagi marcati con un “Follow Up”, tendo ad essere un filino maniacale nell’organizzazione delle mie cose e sapere che ho qualcosa da fare che non ho ancora fatto mi infastidisce abbastanza.
Giusto per capirci, per me sarebbe impossibile avere una Inbox con dei messaggi non letti, quindi nella pause una rapida occhiata ed eventuale marcatura con “Follow Up”, e pianificazione se necessaria (Get Things Done), su quelli che mi interessano. Vi garantisco che con circa 300/350 messaggi/giorno è un lavoraccio :-)
In quest’ottica vedere i “Follow Up” che crescono non mi aiuta a rispettare il ritmo del pomodoro.
.m

I file, le cartelle e… questi sconosciuti

Iniziamo con una piccola nota polemica, concedetemelo :-)image
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.
image
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:
image image
Ad ognuno il suo spazio 
Supponiamo adesso di dover distribuire nella solution i seguenti elementi:
interface IEngine
{
    Boolean IsActive { get; }
}

interface IEngine : 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ì:
image
Con dentro il file Engine.cs tutto il necessario? o così:
image
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:
image
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:
image
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