Back home

Модернизация старых систем сначала требует лестницы совместимости.

Действительно полезная часть Copilot — слой за слоем вытягивать среду, вход, тест и границу.

Сначала модернизируйте старую систему и постройте лестницу совместимости

Когда я впервые открыл Java-проект двадцать лет назад, первое, что я увидел, был не запах кода, а запах возраста. Файл build.xml все еще существует, но файл pom.xml отсутствует; структура каталогов старомодна, тестовый вход также старомоден, и даже «может ли он восстановить работоспособный продукт» необходимо повторно подтвердить. Самая распространенная ошибка на этом этапе — сосредоточиться на классах и методах и игнорировать тот факт, что на самом деле модернизация блокируется средой и входом.

Первое, что нужно сделать при модернизации старых систем, — это построить лестницу совместимости. У основания лестницы обычно есть только одно: заставить старую систему стабильно работать в рамках старых правил и желательно служить капсулой времени. Docker, старый JDK, старые инструменты сборки, старые команды тестирования — эти вещи выглядят грубо, но они очень эффективны. Пока эта основа не стоит вертикально, каждое последующее изменение будет примешиваться к новому шуму: сломан ли код или сломана JVM, образ, архитектура и плагины, сказать невозможно.

Затем настала очередь выбора моста. Цель моста очень конкретна: один конец подключен к старому исходному коду, а другой конец — к новой машине. В конечном итоге этот проект пал на Java 8 и Gradle 7.6, которые просто застряли в ограничениях с обеих сторон: Java 17 больше не желает компилировать исходный код Java 1.5, а Java 6 не может работать в собственной среде ARM64. Если мост неправильный, модернизация застрянет в цепочке инструментов; если мост правильный, последующие миграции смогут продвигаться вперед шаг за шагом.

Самое полезное здесь — позволить большой модели выполнять организацию и перевод. Это может помочь перевести логику Ant в Gradle, вернуть каталогам старый макет и удалить эти повторяющиеся и механические конфигурации. Например, явно укажите каталог исходного кода на старый путь и добавьте пользовательскую задачу для запуска старого теста 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
}

Смысл этой конфигурации состоит в том, чтобы сделать правила старого мира явными. Самое неприятное в старых проектах зачастую не отсутствие способностей, а эти способности скрыты в привычках. Тест запускается через запись main(), исходный код помещается в старый каталог, а сборка записывается с учетом пути в эпоху Ant. Второй пилот может сэкономить здесь время, но он экономит время перевода, а не время принятия решений.

Время принятия решения не может быть передано на аутсорсинг. Gradle 8 выглядит новее, Java 17 выглядит более современно, а прыжок вверх тоже выглядит чище, но эти варианты могут не удовлетворять ограничениям старого исходного кода и старых тестов одновременно. Самый большой страх при модернизации — рассматривать обновление инструментов как прогресс, а выполнение команд — как понимание системы. Пока проект не достиг операционного базового уровня, «зеленое» тестирование не считается победой, его можно рассматривать только как отсутствие на данный момент выхода на открытую поверхность.

Подход, которому я больше доверяю, заключается в том, чтобы сначала разбить проблему на четыре уровня: можно ли ее запустить, можно ли ее редактировать, можно ли ее протестировать и можно ли ее изменить. Первый уровень — воспроизведение сцены, второй уровень — определение моста, третий уровень — определение того, что сохранил старый тест, и четвертый уровень — настоящий рефакторинг. Второй пилот особенно полезен на первых двух уровнях. Он подходит для физической работы с изучением журналов и структур каталогов, а также для объединения фрагментированных подсказок в удобочитаемую карту. На четвертом уровне модель должна отвечать только за транспортировку и подсказки, а люди должны полагаться на людей в принятии решений.

Самый ценный результат модернизации старой системы — превратить кучу вещей, которые «должны работать» в «вещи, которые действительно работают, и мы знаем, почему они работают». Как только эта лестница совместимости будет установлена, последующий демонтаж будет иметь ритм, а изменения будут иметь границы. Второй пилот в это время подобен помощнику на передовой, держащему фонарик, чтобы посмотреть на возраст, вход и зависимости. Что действительно определяет направление, так это оценка истории старой системы.

FAQ

What to read next

Related

Continue reading