Back home

La modernizzazione dei vecchi sistemi richiede innanzitutto la compatibilità

La parte veramente utile di Copilot è estrarre l'ambiente, l'ingresso, il test e il confine strato per strato.

Modernizzare prima il vecchio sistema e costruire la scala di compatibilità

La prima volta che ho aperto un progetto Java di vent’anni fa, la prima cosa che ho visto non è stato l’odore del codice, ma l’odore dell’età. Il build.xml è ancora lì, ma il pom.xml non c’è; la struttura delle directory è antiquata, anche l’ingresso del test è antiquato e anche “se può ricostruire un prodotto eseguibile” deve essere riconfermato. L’errore più comune in questa fase è concentrarsi su classi e metodi e ignorare che ciò che realmente blocca la modernizzazione è l’ambiente e l’ingresso.

La prima cosa da fare quando si modernizzano i vecchi sistemi è costruire una scala di compatibilità. La base della scala di solito ha solo una cosa: far funzionare stabilmente il vecchio sistema entro le vecchie regole e preferibilmente fungere da capsula del tempo. Docker, vecchio JDK, vecchi strumenti di compilazione, vecchi comandi di test, queste cose sembrano rozze, ma sono molto efficaci. Finché questa base non è in posizione verticale, ogni modifica successiva mescolerà nuovo rumore: se è il codice ad essere rotto, o la JVM, l’immagine, l’architettura e i plug-in ad essere rotti, è impossibile dirlo.

Poi è stata la volta della scelta del ponte. L’obiettivo del bridge è molto specifico: un’estremità è collegata al vecchio codice sorgente e l’altra estremità è collegata alla nuova macchina. Questo progetto alla fine è caduto su Java 8 e Gradle 7.6, che si sono limitati a rispettare i vincoli di entrambe le estremità: Java 17 non è più disposto a compilare il codice sorgente di Java 1.5 e Java 6 non può essere eseguito nell’ambiente nativo di ARM64. Se il ponte è sbagliato, la modernizzazione rimarrà bloccata nella catena degli strumenti; se il ponte è giusto, le migrazioni successive potranno procedere passo dopo passo.

La cosa più utile qui è lasciare che il modello grande si occupi dell’organizzazione e della traduzione. Può aiutare a tradurre la logica di Ant in Gradle, a mappare nuovamente le directory sul vecchio layout e a eliminare quelle configurazioni ripetitive e meccaniche. Ad esempio, punta esplicitamente la directory del codice sorgente al vecchio percorso e aggiungi un’attività personalizzata per eseguire il vecchio test main():

java {
    sourceCompatibility = JavaVersion.VERSION_1_5
    targetCompatibility = JavaVersion.VERSION_1_5
}
sourceSets {
    main {
        java {
            srcDirs = ['java']
        }
    }
}
tasks.register('runLegacyTest', JavaExec) {
    mainClass.set(project.findProperty('mainClass'))
    classpath = sourceSets.main.runtimeClasspath
}

Il significato di questa configurazione è rendere esplicite le regole del vecchio mondo. La cosa più problematica nei vecchi progetti spesso non è la mancanza di capacità, ma quella capacità è nascosta nelle abitudini. Il test viene eseguito tramite la voce main(), il codice sorgente viene inserito nella vecchia directory e la build viene scritta assumendo il percorso nell’era Ant. Copilot può risparmiare tempo qui, ma fa risparmiare tempo di traduzione, non di giudizio.

Il tempo del giudizio non può essere esternalizzato. Gradle 8 sembra più nuovo, Java 17 sembra più moderno e anche saltare direttamente verso l’alto sembra più pulito, ma queste opzioni potrebbero non soddisfare i vincoli del vecchio codice sorgente e dei vecchi test allo stesso tempo. La paura più grande nella modernizzazione è considerare gli aggiornamenti degli strumenti come un progresso e l’esecuzione dei comandi come la comprensione del sistema. Finché un progetto non ha centrato la linea di base operativa, i test ecologici non sono considerati una vittoria, possono essere considerati solo come non aver raggiunto la superficie esposta per il momento.

L’approccio di cui mi fido di più è quello di suddividere innanzitutto il problema in quattro livelli: se può essere eseguito, se può essere modificato, se può essere testato e se può essere modificato. Il primo livello è riprodurre la scena, il secondo livello è determinare il bridge, il terzo livello è determinare cosa ha salvato il vecchio test e il quarto livello è il vero e proprio refactoring. Copilot è particolarmente utile nei primi due livelli. È adatto per il lavoro fisico seguendo registri e strutture di directory e per mettere insieme indizi frammentati in una mappa leggibile. Al quarto livello, il modello dovrebbe essere responsabile solo del trasporto e dei suggerimenti, e le persone devono fare affidamento sulle persone per prendere decisioni.

Il risultato più prezioso della modernizzazione del vecchio sistema è quello di trasformare un insieme di cose che “dovrebbero funzionare” in “cose che funzionano davvero e sappiamo perché funzionano”. Una volta stabilita questa scala di compatibilità, il successivo smantellamento avrà un ritmo e i cambiamenti avranno dei confini. Il copilota è come un assistente in prima linea in questo momento, con in mano una torcia per osservare l’età, l’ingresso e le dipendenze. Ciò che determina realmente la direzione è il giudizio sulla storia del vecchio sistema.

FAQ

What to read next

Related

Continue reading