Il giardino giapponese del codice
Un giardino giapponese non e mai "finito". Ogni giorno qualcuno pota un ramo, sposta un sasso, rastrella la ghiaia. La bellezza non nasce da un singolo atto di creazione ma dalla cura costante, iterativa, paziente. Il codice funziona allo stesso modo: la qualita non si raggiunge con un grande refactoring eroico, ma con mille piccoli miglioramenti quotidiani.
In Soft PHP MVC, la code review non e un evento — e un processo continuo. Ogni volta che si lavora su un file, si guarda anche il codice circostante. Se qualcosa "fa storcere il naso", viene annotato, proposto, migliorato. Non domani, non nel prossimo sprint: adesso, mentre il contesto e fresco nella mente.
Questa filosofia si riflette in un file specifico del progetto: refactoring.md. Non e documentazione pubblica — e un diario privato di osservazioni. Ogni volta che si incontra codice migliorabile, viene annotato: quale file, quale problema, quale soluzione proposta. Il file cresce organicamente, e le annotazioni diventano task che vengono risolti nel flusso naturale del lavoro.
Rector: il giardiniere automatico
vendor/bin/rector e il primo strumento della catena di qualita. Analizza il codice e applica trasformazioni automatiche: aggiunge #[\Override] ai metodi che sovrascrivono, converte in readonly le property immutabili, promuove parametri del costruttore, modernizza la sintassi. 108 file trasformati nella migrazione a PHP 8.4 — non a mano, non con find-and-replace, ma con trasformazioni AST che comprendono la struttura del codice.
Il valore di Rector non e nelle singole trasformazioni: e nella sistematicita. Un umano puo dimenticare un #[\Override] qui e la. Rector no. E questa e la differenza tra "buone intenzioni" e "garanzia strutturale" — una distinzione che nel software fa la differenza tra un progetto che invecchia bene e uno che accumula debito tecnico.
Come funziona Rector sotto il cofano
Rector non lavora con espressioni regolari o pattern matching testuale. Usa il PHP Parser di Nikita Popov per costruire un Abstract Syntax Tree (AST) del codice, applica le trasformazioni sull'albero, e rigenera il codice sorgente. Questo approccio e fondamentalmente diverso da un find-and-replace:
- Comprende il contesto — sa se un metodo sovrascrive effettivamente un genitore, non cerca solo la keyword "function"
- Rispetta la formattazione — le trasformazioni preservano lo stile del codice esistente
- E componibile — piu regole possono essere applicate in sequenza senza conflitti
- E reversibile — se una trasformazione causa problemi, basta un git revert
Nel progetto Soft PHP MVC, la configurazione di Rector in rector.php definisce i set di regole attivi. Il --dry-run mostra le trasformazioni proposte senza applicarle — essenziale per il workflow pre-push dove si vuole verificare senza modificare.
Da 596 a 813 test: la fiducia si misura
217 test aggiunti in una sessione. Non per raggiungere una percentuale di coverage, ma per coprire comportamenti reali: casting dei modelli, edge case del query builder, paginazione ai bordi, helper con input vuoti. Ogni test e un'asserzione su come il codice si comporta — e un contratto con il futuro.
Il filosofo pragmatista William James definiva la verita come "cio che funziona". Nel software, un test e una definizione operativa di verita: se il test passa, il comportamento e corretto. Se il test fallisce, qualcosa e cambiato che non doveva cambiare. Non c'e spazio per interpretazioni, non c'e ambiguita. E questa certezza — parziale, locale, ma concreta — e cio che rende possibile il refactoring senza paura.
Cosa testare e cosa non testare
Non ogni riga di codice merita un test dedicato. La scelta di cosa testare in Soft PHP MVC segue criteri pragmatici:
- Logica di business — casting dei modelli, validazione, calcoli: testati sempre perche un errore qui e un bug in produzione
- Edge case — paginazione con zero risultati, query con WHERE vuoto, input null: i confini sono dove nascono i bug
- Regressioni — ogni bug fixato genera un test che impedisce la regressione: il bug non tornera mai
- Integrazioni — il query builder genera SQL corretto per ogni driver: testato perche le differenze tra database sono subdole
Non vengono testati: getter e setter banali, costruttori senza logica, configurazione statica. Il tempo investito nei test deve avere un ritorno in termini di fiducia — testare l'ovvio non aggiunge fiducia, aggiunge solo tempo di esecuzione.
Il pre-push come rituale
Prima di ogni push, una sequenza obbligatoria: vendor/bin/phpunit, poi vendor/bin/rector --dry-run. Se qualcosa fallisce, si corregge prima di pushare. Non dopo, non "lo fixo nel prossimo commit": prima. E un rituale nel senso positivo del termine — un gesto ripetuto che costruisce disciplina e fiducia nel codice che viene condiviso.
Questa pratica si ispira al principio dei Boy Scout: lascia il campeggio piu pulito di come l'hai trovato. Ogni push dovrebbe migliorare la codebase, non degradarla. E il pre-push check e la barriera che impedisce di condividere codice che non soddisfa gli standard del progetto.
La catena di qualita completa
Il workflow di qualita in Soft PHP MVC non si limita al pre-push. E una catena che opera a diversi livelli:
- Durante la scrittura — l'IDE segnala errori di tipo, metodi mancanti, import non usati in tempo reale
- Prima del commit — revisione manuale delle modifiche con
git diffper verificare che non ci siano debug statements o codice temporaneo - Prima del push — PHPUnit per i test, Rector dry-run per la conformita stilistica
- Dopo il push — code review proattiva che annota miglioramenti futuri in
refactoring.md
Il debito tecnico come debito morale
Ward Cunningham, che conio la metafora del debito tecnico, la intendeva come un prestito consapevole: spedisci codice imperfetto oggi, sapendo che dovrai tornare a migliorarlo. Il problema e che il debito tecnico, come quello finanziario, accumula interessi. E gli interessi li paga chi viene dopo — che spesso sei tu stesso, sei mesi dopo, quando hai dimenticato perche quel workaround esisteva.
Il refactoring continuo e il modo per tenere il debito sotto controllo. Non eliminarlo — quello e impossibile in un progetto vivo — ma impedire che cresca fino a paralizzare lo sviluppo. Ogni #[\Override] aggiunto, ogni stringa magica sostituita con un enum, ogni test che copre un edge case: sono pagamenti sul debito. Piccoli, costanti, sostenibili.
La metafora del debito tecnico come debito morale aggiunge una dimensione spesso trascurata. Il codice che lasci non e solo un artefatto tecnico — e un messaggio al tuo futuro te stesso e a chiunque lavorera su quel progetto. Codice curato dice: "ho rispettato il tuo tempo". Codice trascurato dice: "arrangiati". Il refactoring, in questa luce, non e un'attivita opzionale per quando "c'e tempo": e un dovere professionale verso chi verra dopo.