Abbiamo inziato a parlare di Fluent Interfaces.
Perchè una Fluent Interface?
2 motivi:
  1. è un gran comodo poter “guidare” l’utilizzatore finale facendo si che l’intellisense vi proponga solo le cose sensate per il contesto corrente;
  2. è un gran facile leggere codice scritto in maniera fluente;
è tutto? sni… :-)
Nonostante sia un fan di Unit testing e di TDD sono soprattutto innamorato di san csc.exe e adoro gli errori del compilatore, quindi tutto ciò che posso far diventare fortemente strongly-typed diventerà fortemente strongly-typed.
Questo effettivamente è terribile:
var worker = new BackgroundWorker();
worker.DoWork += ( s, e ) => 
{
    var arg = ( int )e.Argument;
};

worker.RunWorkerAsync( "this should be an integer :-)" );
perchè sbomba da paura a runtime :-)
Un altro problema…
Scrivo questo:
image
Notate che l’intellisense mi propone ancora il metodo “AndAfterDo( … )” e pure il metodo “Cancel()” entrambi senza senso in questo contesto? il primo perchè già usato mentre il secondo inutile se il worker non è ancora in esecuzione.
Quindi una delle difficoltà vere del design, e della realizzazione, di una buona Fluent Interface è quella di essere in grado di offrire una “coding experience” degna del suo nome, come ad esempio questa:
image image
dove dopo aver fatto la configurazione del worker posso solo ed esclusivamente mandarlo in esecuzione rendendo di fatto impossibile che il programmatore sbagli ad utilizzare il componente.
Al prossimo giro vediamo come risolvere questo e un altro interessante problema del design di un componente che espone una Fluent Interface.
.m