venerdì 3 marzo 2017

Fluent Interfaces e method-chaining

La prima volta che ho visto una "fluent" interface è stato quando tanti anni fa ho studiato Java NIO.
Oggi la fluent interface è una buona prassi di molti linguaggi di programmazione, e in modo un po' ridicolo qualcosa di non accettato in Java stesso.
L'idea di una fluent interface è abbastanza semplice: i mutators dovrebbero ritornare un riferimento all'oggetto che modificano, così da abilitare una method chain, in sostanza:

MyObject foo = ...;
foo.setTitle( 'My Object' ).setVisible( true ).setDescription( 'Here the description' );

che sicuramente risulta piu' compatto rispetto al classico

MyObject foo = ...;
foo.setTitle( 'My Object' );
foo.setVisible( true );
foo.setDescription( 'Here the description' );

Ora, che si tratti di una versione piu' leggibile o meno è una questione di gusti, sicuramente avere linee troppo lunghe non aumenta la leggibilità, ma considerando che molti linguaggi ammettono la gestione flessibile degli spazi, una via di mezzo fra la method-chain e l'approccio classico diventa

MyObject foo = ...;
foo.setTitle( 'My Object' )
   .setVisible( true )
   .setDescription( 'Here the description' );

abbstanza compatto e leggibile, grazie ad una buona indentazione.

Ma il vero vantaggio della fluent interface si nota, a mio avviso, nell'uso combinato dei conditionals. Si consideri il seguente esempio:


MyObject foo = ...;
if ( init ) {
  foo.setTitle( 'My Object' );
  foo.setVisible( true );
  foo.setDescription( 'Here the description' );
}

che può agilmente essere riscritto eliminando la necessità di piu' istruzioni e le parentesi graffe:

MyObject foo = ...;
if ( init )
  foo.setTitle( 'My Object' );
     .setVisible( true );
     .setDescription( 'Here the description' );


E questo a me personalmente piace molto!

Ahimé i Java Beans, stupidamente, si rifiutano di accettare la fluent interface e abilitare la method-chain. Infatti la specifica impone che i mutators siano di tipo "void", ossia non ritornino nulla. E i framework aderiscono spesso severamente a questa opzione, non riconoscendo quindi i mutators che possono ritornare un riferimento all'istanza stessa.

Nessun commento: