Back home

Modernizacja starych systemów wymaga najpierw drabiny kompatybilności

Naprawdę przydatną częścią Copilot jest wyciąganie środowiska, wejścia, testowania i ograniczania warstwa po warstwie.

Najpierw zmodernizuj stary system i zbuduj drabinę kompatybilności

Kiedy po raz pierwszy otworzyłem projekt Java sprzed dwudziestu lat, pierwszą rzeczą, którą zobaczyłem, nie był zapach kodu, ale zapach wieku. Plik build.xml nadal tam jest, ale nie ma pliku pom.xml; struktura katalogów jest przestarzała, wejście do testu również jest staromodne i nawet „czy można odbudować działający produkt” wymaga ponownego potwierdzenia. Najczęstszym błędem na tym etapie jest skupienie się na zajęciach i metodach oraz ignorowanie tego, co tak naprawdę blokuje modernizację, to otoczenie i wejście.

Pierwszą rzeczą do zrobienia podczas modernizacji starych systemów jest zbudowanie drabiny kompatybilności. Podstawa drabiny ma zazwyczaj tylko jedno: sprawić, by stary system działał stabilnie na starych zasadach, a najlepiej służyć jako kapsuła czasu. Docker, stary JDK, stare narzędzia do kompilacji, stare polecenia testowe – te rzeczy wyglądają prymitywnie, ale są bardzo skuteczne. Dopóki ta podstawa nie będzie wyprostowana, każda kolejna zmiana będzie generować nowy szum: nie da się stwierdzić, czy uszkodzony jest kod, czy JVM, obraz, architektura i wtyczki.

Potem przyszła kolej na wybór mostu. Cel mostu jest bardzo konkretny: jeden koniec jest podłączony do starego kodu źródłowego, a drugi koniec do nowej maszyny. Projekt ten ostatecznie padł na Java 8 i Gradle 7.6, które po prostu utknęły w ograniczeniach obu końców: Java 17 nie chce już kompilować kodu źródłowego Java 1.5, a Java 6 nie może działać w natywnym środowisku ARM64. Jeśli most będzie nieprawidłowy, modernizacja utknie w łańcuchu narzędzi; jeśli most będzie właściwy, kolejne migracje będą mogły krok po kroku posuwać się do przodu.

Najbardziej użyteczną rzeczą jest pozwolenie dużemu modelowi na zorganizowanie i tłumaczenie. Może pomóc w przetłumaczeniu logiki Anta na Gradle, zmapowaniu katalogów z powrotem do starego układu i usunięciu powtarzalnych i mechanicznych konfiguracji. Na przykład jawnie wskaż katalog kodu źródłowego na starą ścieżkę i dodaj niestandardowe zadanie, aby uruchomić stary 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
}

Znaczenie tej konfiguracji polega na jasnym ukazaniu zasad starego świata. Najbardziej uciążliwą rzeczą w starych projektach często nie jest brak umiejętności, ale ta umiejętność ukryta jest w nawykach. Test przeprowadzany jest poprzez wpis main(), kod źródłowy umieszczany jest w starym katalogu, a kompilacja jest zapisywana przy założeniu ścieżki z ery Anta. Drugi pilot może tutaj zaoszczędzić czas, ale oszczędza czas tłumaczenia, a nie czasu na ocenę.

Nie można zlecić wykonania wyroku podmiotowi zewnętrznemu. Gradle 8 wygląda na nowszą, Java 17 wygląda na bardziej nowoczesną, a bezpośrednie przeskakiwanie w górę również wygląda czyściej, ale te opcje mogą nie spełniać jednocześnie ograniczeń starego kodu źródłowego i starych testów. Największą obawą związaną z modernizacją jest traktowanie aktualizacji narzędzi jako postępu, a uruchamianie poleceń jako zrozumienia systemu. Dopóki projekt nie osiągnął operacyjnego poziomu bazowego, zielone testy nie są uważane za zwycięstwo, można je uznać jedynie za to, że na razie nie uderzają w odsłoniętą powierzchnię.

Podejście, które darzę większym zaufaniem, polega na podzieleniu problemu na cztery poziomy: czy można go uruchomić, czy można go edytować, czy można go przetestować i czy można go zmodyfikować. Pierwszy poziom to odtworzenie sceny, drugi poziom to określenie mostu, trzeci poziom to określenie, co zapisał stary test, a czwarty poziom to rzeczywista refaktoryzacja. Copilot jest szczególnie przydatny na dwóch pierwszych poziomach. Nadaje się do fizycznej pracy z logami i strukturami katalogów oraz do łączenia fragmentarycznych wskazówek w czytelną mapę. Na czwartym poziomie model powinien być odpowiedzialny jedynie za transport i podpowiedzi, a ludzie muszą polegać na ludziach przy podejmowaniu decyzji.

Najcenniejszym rezultatem modernizacji starego systemu jest zamiana wielu rzeczy, które „powinny działać” na „rzeczy, które faktycznie działają i wiemy, dlaczego działają”. Po ustaleniu tej drabiny kompatybilności dalszy demontaż będzie miał rytm, a zmiany będą miały granice. Drugi pilot jest w tym czasie jak asystent na pierwszej linii frontu, trzymający latarkę, aby sprawdzić wiek, wejście i zależności. Tym, co tak naprawdę wyznacza kierunek, jest ocena historii starego systemu.

FAQ

What to read next

Related

Continue reading