La fluidità del codice

Ho rivisto recentemente uno screencast sul TDD di Piergiuliano Bossi. Mi ha fatto pensare l’accento posto sulla “fluidità del codice”. Questa proprietà era messa in relazione diretta con il refactoring. In entrambi i sensi: la fluidità favorisce il refactoring e il refactoring favorisce la fluidità. Ad ogni modo Bossi poneva la fluidità come condizione imprescindibile per poter realizzare un design incrementale.

Non voglio qui entrare nel merito di quanto design sia possibile e opportuno realizzare ex-ante o ex-post (argomento che ha già comportato fiumi d’inchiostro o tera di bit che dir si voglia). Quello su cui volevo concentrarmi era la fluidità. Mi chiedevo se c’è un modo più formale per definirla. E nel frattempo in cui continuo a ragionare su eventuali definizioni formali, provo a mettere il concetto di fluidità in relazione diretta con la “paura” che il programmatore prova davanti al codice da modificare.

Penso che questa idea della “paura” non sia sostanzialmente nuova, l’intero mondo XP/TDD ha sempre fatto riferimento alle tecniche agili come modi per aumentare la serenità (e quindi ridurre la paura) nel mettere mano a del codice, tuttavia con questo post mi propongo di sprecare ancora due parole sulle relazioni tra fluidità, refactoring e paura.

Se come programmatore provo paura e mi sento in ansia davanti alla modifica a del codice (esempio un aggiunta funzionale) le possibilità sono due: o non conosco il codice abbastanza approfonditamente, oppure il codice è molto rigido e scarsamente fluido.

(Sto pensando che forse il termine più corretto sarebbe duttile e/o malleabile: fluido forse si associa all’idea di liquido, mentre duttile/malleabile si associa all’idea di qualcosa a cui è facile far cambiare forma. Diciamo che riferito al sistema nel suo complesso i termini duttile/malleabile sarebbero più adatti, tuttavia, se riferito al codice, è per il momento più adatto il termine fluido.)

Tornando ai due casi di paura: sia nel caso di conoscenza non approfondita che nel caso di codice eccessivamente rigido, si rende necessaria una seduta di refactoring.

Nel primo caso il refactoring è un ottimo metodo per prendere confidenza con il codice: cambiare i nomi alle variabili, riorganizzare un po’ le funzioni erano ricette che già il libro storico di Fowler offriva. Se come programmatore riesci a fare queste operazioni senza impazzire questo significa che il codice, oltre che logico ed essenziale, è sufficientemente fluido. Se viceversa una minima modifica compromette i test case in modi imprevedibili questo significa che il codice è eccessivamente rigido e cristallizzato.

(Probabilmente perché il sistema è eccessivamente rigido su una posizione di equilibrio instabile e non naturale rispetto alla sua “forma” intrinseca?  Rubo un po’ di termini a Carlo Pescio e ai suoi ragionamenti sulla sintesi della forma… potrebbe essere uno spunto per altri post.)

Tornando al secondo caso di paura: conosco il codice e ho già la percezione di un’eccessiva rigidità. Insomma, in entrambi i casi sono in difficoltà prima ancora di pensare a come implementare la mia aggiunta funzionale.

Soluzione valida in entrambi i casi? Refactoring!

In effetti per uscire dall’impasse le possibilità sono due: o accetto di fare una modifica il più localizzata possibile e che comprometta il meno possibile (si tratta sostanzialmente della tecnica “finger crossing” ;-)),  oppure procedo con un refactoring, anche radicale, fino a che il software non abbia una forma per la quale l’aggiunta funzionale che devo fare è semplicemente una logica estensione rispetto ai meccanismi base.

La prima strada si può certamente perseguire, l’importante è avere chiara la consapevolezza che questa scelta significa contribuire a condannare il sistema all’agonia e alla morte. Infatti facendo una modifica secondo questa modalità pregiudico le possibilità future di rendere il sistema più fluido e quindi metto in conto che quel sistema non avrà futuro e che prima o poi dovrà essere sostituito.

Ovviamente rimane responsabilità del programmatore/designer prendere una decisione del genere, e in certi casi potrebbe persino essere giustificata: prendiamo ad esempio la necessità di apportare una modifica molto localizzata ad un sistema legacy solo per agevolarne il porting al nuovo sistema che è ancora in via di costruzione. L’importante è che il programmatore sia chiaramente consapevole delle conseguenze della sua scelta.

Nel secondo caso, quello in cui si accetta un refactoring anche pesante pur di permettere al sistema di rimanere fluido e sostanzialmente flessibile rispetto alla nuova forma, si allunga la vita al sistema e lo si mantiene “agile”.

In pratica la fluidità è un termine alternativo per la capacità del sistema di essere “in forma”: un sistema con del codice fluido è un sistema “agile” ossia un sistema “in forma”.

Il gioco di parole è tra il serio e il faceto e mette insieme termini ginnici, termini di TDD/XP e termini nati nel mondo dei design pattern di derivazione C. Alexander. Inoltre l’intero post fa riferimento un po’ al sistema e un po’ ai metodi per crearlo.

Insomma, sono chiaramente consapevole di aver utilizzato in modo non uniforme i termini fluido, agile, rigido, “in forma” a volte in riferimento al sistema a volte in riferimento al metodo di costruzione ed, infine, a volte in riferimento al codice che lo compone. Ma questa confusione era parte dell’obbiettivo del post che voleva anche un po’ giocare con le parole per “ragionare a voce alta”  su situazioni che paiono astratte e sono invece parte della quotidianità di un lavoro di design e programmazione.

Beh anche un blog può essere fluido (in un altro senso ancora); l’importante è che mantenga la capacità di far ragionare sia chi scrive i post sia, si spera, chi li legge. Se non raggiunge questo obiettivo si parla non di post “rigido” bensì, più propriamente, di post “confusionario”: ai posteri l’ardua sentenza. ;-)

Comments

  1. Articolo molto interessante.

    Leggendolo pensavo… e se la fluidità fosse pure inversamente proporzionale all’energia che devo impiegare per rimettere in ordine le cose dopo la modifica?
    a) Più fluido = poca energia, poco tempo per sistemare
    b) Mediamente fluido = mi metto di impegno ma dopo un po’ di lavoro combino
    c) Cristallizzato = Ho creato, con la modifica, un problema irriducibile. Torno indietro e rinuncio.

    Magari il termine “resilienza” inquadrerebbe meglio la problematica. O forse no.
    Vabbé, ho detto la mia.

    Ciao

    Marzio

  2. Questo articolo descrive esattamente il dilemma che il programmatore deve affrontare ogni giorno nel suo lavoro! Posso immaginare il codice “appena creato” veramente fluido e caldo, poi col passare del tempo e con l’innesto di modifiche “finger-crossing”, la sua viscosità inizia ad aumentare, il refactoring che tarda sempre di più ad arrivare ed ecco che si passa dalla viscosità alla semplice elasticità e quindi ad accettare gradi di elasticità sempre inferiori fino ad arrivare al un solido freddo monoblocco :( … beh si spera di riuscire ad intervenire prima di questo stadio finale… poi per associazione… se il refactoring serve a mantenere il codice fluido, cosa si può dire dell’analoga attività che potrebbe mantenere il “letto del fiume” con meno anse possibili? … beh probabilmente quest’ultima osservazione è fuori tema…
    Ciao
    Luca

  3. Lorenzo says:

    Ottimo post, mi ha fatto riflette su questo aspetto importante :)

Policy per i commenti: Apprezzo moltissimo i vostri commenti, critiche incluse. Per evitare spam e troll, e far rimanere il discorso civile, i commenti sono moderati e prontamente approvati poco dopo il loro invio.


Speak Your Mind

*

Current day month ye@r *