Ovvero: come una delle soluzioni che sembravano più intelligenti si è rivelata una delle più pericolose.
Ho iniziato a programmare “seriamente” nel 1999 con Visual Basic 6, e le variabili globali VB6 sono state la prima, grande lezione di ingegneria del software che non sapevo di dover ancora imparare.
Come molti della mia generazione, in parallelo agli studi, c’erano stati i corsi di programmazione nelle scuole professionali private, gli esercizi, i piccoli programmi… poi, all’improvviso, il meraviglioso mondo reale.
Il mio primo software importante è stato un sistema di controllo degli accessi per le aree di cantiere di una centrale Enel. Ogni giorno transitavano circa 400-500 persone e centinaia di mezzi tra ingressi pedonali e veicolari. Non era il classico progettino scolastico: se il programma si fermava o produceva dati errati, le attività di cantiere ne subivano direttamente le conseguenze.
Avevo tanta voglia di imparare e la fortuna di lavorare a contatto con programmatori più esperti di me, con una seniority importante. Erano quelli che allora chiamavamo “i guru”.
Condividevano esperienza, consigli e quelle che tutti consideravano le best practice.
Ripensandoci oggi, dopo quasi trent’anni di lavoro, mi viene da sorridere.
O forse, in certi casi, mi viene la nausea… 😄
Non perché fossero incompetenti.
Anzi.
Erano professionisti preparati, che avevano costruito sistemi importanti quando Internet era ancora agli inizi, la documentazione era scarsa e imparare significava soprattutto osservare chi ne sapeva più di te.
Semplicemente lavoravano con gli strumenti, le conoscenze e la cultura tecnica disponibili in quel periodo.
Programmare era molto diverso
Oggi chi inizia a sviluppare trova migliaia di libri, video, blog, corsi online, Stack Overflow, GitHub, documentazione praticamente infinita e decenni di esperienza collettiva sedimentata.
Nel 1999 era tutta un’altra storia.
L’ingegneria del software era una disciplina conosciuta soprattutto in ambito accademico. Chi proveniva da percorsi professionali, difficilmente aveva sentito parlare di progettazione del software nel senso moderno del termine.
Termini come SOLID, Clean Code, Dependency Injection, Domain Driven Design, Inversion of Control erano praticamente assenti dalle conversazioni quotidiane di chi sviluppava software gestionale.
Ma soprattutto mancava una sensibilità che oggi consideriamo quasi ovvia: la Separation of Concerns, cioè la separazione delle responsabilità.
Il concetto, in realtà, non è affatto recente.
Fu introdotto da Edsger Dijkstra già negli anni Settanta.
Tuttavia, fuori dagli ambienti accademici, ha impiegato parecchi anni prima di diventare patrimonio comune.
Tra il 2003 e il 2010 qualcosa cambiò. L’arrivo di .NET, la diffusione di Java Enterprise, i Design Pattern, libri come Refactoring di Martin Fowler e Clean Code di Robert C. Martin, insieme alla nascita di community tecniche e di Stack Overflow, portarono finalmente questi concetti anche allo sviluppatore “normale”.
Prima di allora era assolutamente normale trovare una Form che:
- interrogava direttamente il database;
- costruiva query SQL;
- eseguiva controlli di business;
- aggiornava l’interfaccia;
- stampava report;
- gestiva la logica applicativa.
Tutto nello stesso evento Click di un pulsante.
Oggi ci sembra assurdo.
All’epoca era semplicemente il modo in cui si sviluppava.
Si imparava osservando il collega o il consulente che “lui sì che ne sa”.
E se quel collega faceva una cosa in un certo modo… automaticamente diventava “il modo giusto”.
L’obiettivo principale non era scrivere codice elegante.
Era scrivere codice che funzionasse.
E possibilmente consumasse poca memoria.
Per tutto il resto… ci si sarebbe pensato dopo.
Spoiler: quel “dopo”, nella maggior parte dei casi, non arrivava mai.
Il museo degli orrori (col dovuto affetto, ovviamente!)
Ripensando a quegli anni mi vengono in mente tecniche che oggi farebbero sorridere — e probabilmente storcere il naso — a qualsiasi sviluppatore.
Una fra tutte.
Due TextBox sovrapposte perfettamente nella stessa posizione.
Ognuna collegata a un DataSource differente.
Quando serviva cambiare comportamento bastava nasconderne una e mostrare l’altra.
Geniale, no?
In realtà no.
Perché il giorno in cui tu — o peggio ancora un collega — dovevi modificare quella schermata, iniziava una vera caccia al tesoro.
Aprivi la Form.
Vedevi una sola TextBox.
La spostavi di qualche pixel.
Compilavi.
Ed ecco comparire magicamente una seconda TextBox che non avevi mai visto.
“Ma da dove diavolo è uscita?”
Era sempre stata lì.
Semplicemente nascosta.
L’IDE non ti aiutava a capire cosa stesse succedendo.
Il codice ancora meno.
Funzionava?
Sì.
Era mantenibile?
Nemmeno per sogno.
Eppure… si faceva così.
Poi c’erano loro: le variabili globali VB6
Ma c’è una pratica che più di tutte mi ha fatto cambiare completamente modo di pensare.
Le variabili globali.
Le variabili globali VB6 non erano un trucchetto da programmatori pigri: Visual Basic 6 aveva addirittura lo scope Global.
Non era una scorciatoia.
Era una funzionalità ufficiale del linguaggio.
E veniva usata tantissimo.
Dovevi passare il codice cliente da una Form all’altra?
Variabile globale.
L’utente autenticato?
Variabile globale.
L’ID del documento corrente?
Variabile globale.
Una configurazione?
Variabile globale.
Il ragionamento era semplicissimo.
“La metto globale… così se un domani mi serve posso accedervi da qualunque parte.”
All’epoca sembrava una soluzione brillante.
Oggi mi rendo conto che era l’inizio del problema.
L’inganno delle variabili globali VB6
Le variabili globali VB6 sono un inganno.
Non perché non funzionino.
Anzi.
Funzionano benissimo.
Ed è proprio questo il problema.
Ti danno l’impressione di eliminare complessità.
In realtà non eliminano assolutamente nulla.
La spostano nel futuro.
Oggi risparmi dieci minuti evitando di progettare correttamente il passaggio delle informazioni.
Tra sei mesi spenderai tre ore cercando di capire chi ha modificato quel valore.
È un debito tecnico con interessi altissimi.
Ma c’è di più.
Le variabili globali sono l’esatto opposto della Separation of Concerns.
Se un componente ha una responsabilità precisa, dovrebbe conoscere solo le informazioni strettamente necessarie a svolgere quel compito.
Una variabile globale rompe completamente questo principio.
Rende un dato disponibile ovunque.
Qualunque parte dell’applicazione può leggerlo.
Qualunque parte dell’applicazione può modificarlo.
È come lasciare tutte le chiavi dell’azienda appese a un gancio in corridoio.
È comodo.
Fino al giorno in cui qualcuno apre una porta e nessuno riesce più a capire chi sia stato.
Lo stato condiviso è un nemico silenzioso
Con il passare degli anni ho capito una cosa.
Quando una funzione riceve tutto ciò che le serve attraverso i parametri, leggerla è relativamente semplice.
Sai da dove arrivano i dati.
Sai cosa restituisce.
Sai quali effetti produce.
Quando invece quella funzione legge cinque variabili globali…
…non basta più leggere quella funzione.
Devi conoscere tutta l’applicazione.
Perché qualunque altra parte del programma potrebbe aver modificato quei valori.
Ed è qui che nasce il caos.
Non sai più:
- chi ha valorizzato quella variabile;
- quando è stata modificata;
- se il valore è ancora valido;
- se qualcuno la cambierà subito dopo.
Ogni variabile globale aumenta la quantità di programma che devi tenere contemporaneamente nella testa.
E il nostro cervello, per quanto allenato, ha un limite.
Questa, probabilmente, è la ragione tecnica più importante per cui oggi cerchiamo di limitarne l’uso.
Non è una questione di stile.
È una questione di complessità cognitiva.
Anche Option Explicit racconta un’epoca
C’è un altro dettaglio che oggi fa quasi sorridere.
In VB6, se volevi obbligare il compilatore a verificare che tutte le variabili fossero dichiarate, dovevi scrivere in testa al modulo:
vb
Option Explicit
Sì.
Dovevi chiederlo esplicitamente.
Altrimenti bastava scrivere:
vb
Totale = Totle + Importo
Quel banale errore di battitura non generava un errore.
Creava una nuova variabile.
Silenziosamente.
Se oggi raccontassi questa cosa a un giovane sviluppatore probabilmente penserebbe che me la sto inventando.
E invece no.
Era tutto vero.
Il problema non erano le variabili globali VB6 in sé
Ogni tanto sento dire:
“Eh… ma era VB6.”
No.
Il problema non era VB6 in quanto linguaggio.
Mi capita ancora oggi, nel 2026, di mettere mano ad applicazioni sviluppate in Visual Basic 6.
In ambito bancario, assicurativo e industriale esistono ancora moltissimi software VB6 perfettamente funzionanti. Sostituirli avrebbe costi enormi, tempi lunghissimi e rischi che spesso non giustificano una riscrittura completa.
E qui devo essere onesto, anche a costo di rovinare un po’ la morale della favola.
Codice VB6 scritto bene venticinque anni fa, nella mia esperienza, non l’ho praticamente mai trovato.
Quello che trovo oggi, quando metto mano a codice legacy, è esattamente quello che vi ho raccontato finora: variabili globali ovunque, controlli sovrapposti, Form che fanno tutto loro.
Il problema non si è mai risolto da solo con il tempo, semplicemente perché all’epoca nessuno aveva gli strumenti concettuali per farlo diversamente.
Quello che invece ho imparato, tornando su quel codice con gli occhi di oggi, è che si potrebbe scrivere bene anche in VB6. Il linguaggio non lo impediva affatto. Lo permetteva. Semplicemente allora nessuno lo faceva, perché nessuno sapeva ancora come farlo. Esiste del codcie VB6 di oggi, che ha poco da invidiare al codcie attuale. Anzi, le limitazioni offettive del codice obbligano a dei virtuosisimi lodevoli!
Perché sovrapporre due controlli quando puoi modificarne dinamicamente il comportamento?
Perché usare una variabile globale quando puoi passare esplicitamente un parametro?
Perché allargare lo scope di una variabile oltre il necessario?
Il linguaggio aveva certamente i suoi limiti.
Ma la disciplina progettuale non dipende dal linguaggio.
Dipende dalla cultura tecnica dei programmatori.
E quella cultura, alla fine degli anni Novanta, era inevitabilmente diversa da quella che abbiamo oggi.
Non mancava la buona volontà.
Mancavano semplicemente molti degli strumenti concettuali che oggi diamo per scontati.
“Abbiamo sempre fatto così”
C’è una frase che nello sviluppo software mi mette sempre un po’ in allarme.
“Abbiamo sempre fatto così.”
È una frase comprensibile.
Anche io, nel 1999, facevo esattamente quello che vedevo fare ai programmatori più esperti.
Era naturale.
Il problema nasce quando quella frase diventa un alibi per non evolvere.
Conosco sviluppatori della mia generazione che hanno continuato a studiare.
Hanno approfondito l’ingegneria del software.
Hanno scoperto nuovi paradigmi.
Hanno cambiato completamente modo di progettare.
Altri, invece, sono rimasti fermi al modo di lavorare con cui avevano iniziato.
Non perché siano meno intelligenti.
Semplicemente perché il loro contesto lavorativo non li ha mai costretti a cambiare.
Il rischio, però, è che queste abitudini vengano trasmesse ai programmatori più giovani.
Uno sviluppatore junior tende naturalmente a fidarsi di chi ha venti o trenta anni di esperienza.
Ed è giusto così.
Ma trent’anni di esperienza non significano automaticamente trent’anni di crescita.
Significano soltanto trent’anni di lavoro.
Sono due cose profondamente diverse.
La lezione più importante
Se oggi potessi tornare indietro e parlare con il Luigi del 1999, non gli direi di imparare un nuovo linguaggio.
Non gli parlerei di framework (è apparso al pubblico solo 3 anni dopo ed era fantascienza!).
Non gli parlerei nemmeno di Design Pattern (esistenti anche allora!).
Gli direi una cosa molto più semplice.
Ogni dato dovrebbe vivere nell’ambito più piccolo possibile.
Questa è, in fondo, la lezione più semplice che le variabili globali VB6 mi hanno insegnato, anche se ci ho messo anni a metterla davvero a fuoco.
Perché ogni volta che allarghi inutilmente lo scope di una variabile, stai aumentando il numero di punti del programma che potranno modificarla.
E, di conseguenza, stai diminuendo il controllo che hai sul comportamento del software.
È questo il vero inganno delle variabili globali.
Da ragazzo ero convinto che mi dessero più libertà.
Dopo quasi trent’anni di sviluppo ho capito che è vero esattamente il contrario.
Più un dato è globale, meno controllo hai sul tuo software.
E, alla fine, programmare bene significa proprio questo: non scrivere codice che semplicemente funziona oggi, ma costruire software che anche il “te stesso” di cinque anni nel futuro riuscirà a comprendere senza imprecare davanti al monitor.
Perché il codice non si scrive per il compilatore.
Si scrive per il prossimo programmatore che dovrà leggerlo.
E molto spesso… quel programmatore saremo ancora noi.
Un’ultima storia, prima di chiudere
Qualche tempo fa un mio vecchio collega raccontava, ridendo, di un suo ex capo tornato da un corso di good coding in ambito .NET Framework.
Non si è mai capito bene perché al corso ci fosse andato lui, il capo, e non i programmatori. Ma vabbè.
Tornato in ufficio, aveva annunciato solennemente:
“La cosa più importante che ci hanno detto è che un programma, per essere scritto bene, deve avere meno codice possibile. Bisogna scrivere poco codice.”
Il mio collega lo sbeffeggiava proprio per questo.
“E come fai a scrivere poco codice? Non è possibile! Vorrei vedere come farebbero a farlo, quelli che dicono tutte queste fesserie.”
Ecco.
Ripensandoci, mi rendo conto che l’avevano capita male in due. Sia il capo, che aveva sintetizzato il concetto in una frase un po’ troppo comoda, sia il collega, che l’aveva liquidata come una fesseria da corso aziendale.
“Scrivere poco codice” non significa contare i caratteri, né gareggiare a chi scrive la riga più corta.
Significa una cosa molto più precisa: limitare ogni pezzo di codice a una singola responsabilità.
Perché una classe Main di un framework custom non può avere 10.932 righe?
Perché non può contenere Select Case lunghi come un elenco telefonico, che di fatto fanno da handler per mezza applicazione?
Semplce! Non è “tanto codice ben scritto”. È “tanto codice scritto male”! (tanto male!)
È una responsabilità sola, gonfiata all’infinito, che avrebbe dovuto essere spezzata in tante classi, tante funzioni, tanti metodi, ciascuno con un compito preciso e riconoscibile.
Ed è lì che quella classe Main da diecimila righe assomiglia, in fondo, alla stessa identica storia delle variabili globali VB6: qualcosa che sembra comodo perché “tanto sta tutto lì”, finché non tocca a te andarci a mettere le mani.
Anche questo, come lo scope delle variabili, non si impara per intuizione.
Si impara studiando. Studiando ancora. E poi studiando un altro po’.
(cercado di metabolizzare e accettare quello che si sta studiando!)
