Un problema ricorrente nello sviluppo sono le concatenazioni delle operazioni dove si finisce frequentemente nello stesso punto/metodo/funzione!
Solitamente accade questo:
si scrive una funzione e si inizia a riutilizzarla nei vari punti del progetto, man mano che la riutilizziamo si inizia ad aggiungere parametri, condizioni, codice nuovo che serve ad 8 dei 10 punti dove viene utilizzata ma nei 2 casi dove non serve passiamo booleane (con valori di default) per gestire queste eccezioni.
La nostra funzione diventa qualcosa di ingestibile in poco tempo ed il nostro codice perde estensibilità, aumenta la sua rigidità e la possibilità di introdurre nuovi bugs, quindi, diminuisce la nostra produzione!
Ho avuto più volte dibattiti e discussioni con amici e colleghi su questo argomento, alcuni sostengono che ci deve essere un punto unico dove convogliare tutta la funzionalità. Io non sono molto d’accordo con questa filosofia. Ci può essere un punto solo dove gestire/aggiungere una funzionalità solo se questa non invalida lo scopo del metodo ovvero la sua responsabilità (SRP), molte volte le condizioni che aggiungiamo (IF) lo fanno!
La cosa più importante è, avere layer/moduli ben organizzati dove ritroviamo facilmente queste “pseudo” duplicazioni e si possono rivedere e refactorizzare più facilmente essendo isolate, piuttosto che avere un metodo imbuto ingestibile, oppure, logiche simili sparse in giro per il progetto!
Una tecnica molto apprezzata e quella del fluent interface (attenzione non è il builder pattern), dove si creano tante piccole funzionalità e si concatenano insieme per crearne altre più complesse, un po’ come in una catena di montaggio dove ogni punto ha una singola responsabilità. Con questa tecnica se voglio escludere una parte di codice, invece di aggiungere una condizione (IF) che mi esclude quella parte, creo una variante dove quel blocco non esiste nella mia catena.
L’immagine della catena di montaggio è la più efficace per capire questa tecnica, dove posso sempre facilmente riorganizzare la mia pipeline, spostare prima o dopo le varie operazioni, aggiungerne di nuove facilmente, crearne altre parallele simili ed efficaci! Anche con questa tecnica è sempre importante mantenere le varie concatenazioni in un layer separato.
La mia conclusione è che ci troviamo sempre in queste condizioni (capita ancora anche a me) per la fretta di aggiungere nuove funzionalità e scarso refactoring; quando questo sintomo diventa molto frequente, si entra nell’effetto Broken Window e nemmeno la Boyscout Rule ci aiuta più!
Photo by Xiang Hu on Unsplash Xiang Hu