Работа с легаси и большими кодовыми базами

Зрелость инженера проверяется не на чистом проекте с нуля, а на огромной запутанной кодовой базе, которую написали не вы.

Легаси-код — работающий код, который вы боитесь менять: он приносит ценность, но плохо понятен и слабо покрыт тестами.

Почему это ключевой навык

Стартовые курсы учат писать с нуля, а реальная работа — это в основном изменение существующего. Junior теряется в большой кодовой базе: «здесь миллион строк, я ничего не понимаю». Senior спокоен, потому что владеет стратегией: не нужно понимать всё, нужно понять ровно тот путь, который затрагивает твоя задача. Это разница между «прочитать весь город» и «проложить маршрут от А до Б».

Стратегия понимания

ПриёмЧто даёт
Идти от точки входаПрослеживаешь путь данных, а не читаешь подряд
Ставить точки и логиВидишь реальный поток исполнения, а не догадки
Читать тестыТесты — это спецификация поведения в примерах
git blame / историяПонимаешь, ПОЧЕМУ код такой (часто неочевидно)
Спросить старожилаМинута разговора экономит день раскопок

Стратегия безопасных изменений

Главный страх легаси — «тронешь одно, сломается другое». Лекарство — сначала покрыть тестами то, что меняешь. Этот приём называют «характеризующими тестами»: вы пишете тесты, фиксирующие текущее поведение (даже если оно странное), и только потом меняете код. Тесты ловят, если вы что-то задели.

Цикл безопасного изменения легаси:

  1. Понять кусок, который трогаю (только его)
  2. Покрыть текущее поведение тестами (страховочная сеть)
  3. Внести минимальное изменение
  4. Тесты зелёные? -> мёржу маленьким PR
  5. Повторяю; большое улучшение = много мелких безопасных шагов

Полезная мысленная установка при встрече с пугающим легаси — «закон Честертона о заборе»: прежде чем убрать непонятный забор, выясни, зачем его поставили. Странная на вид строчка кода часто оказывается лекарством от давно забытого, но реального бага. Если вы не понимаете, зачем что-то сделано, это повод не удалять, а разобраться: история коммитов, тикеты, разговор со старожилом обычно вскрывают утерянную причину. Уважительное любопытство вместо высокомерного «кто это писал?!» — рабочая позиция инженера, который умеет жить с легаси, а не воюет с ним.

Как работает под капотом

За хаосом легаси почти всегда стоит логика, просто утерянная: код такой не от глупости, а от давления сроков, ушедших людей и забытого контекста. Зрелый инженер не презирает легаси («кто это писал?!»), а относится к нему как археолог: это работающая система, приносившая ценность годами. Уважение к легаси — признак senior; высокомерное «всё переписать» — признак незрелости.

Соблазн «переписать всё»

Junior, столкнувшись с легаси, хочет снести и написать заново. Почти всегда это ловушка: переписывание недооценивает скрытую сложность (легаси кодирует тысячи обработанных краевых случаев), занимает в разы дольше и замораживает развитие продукта. Стратегия зрелых — постепенное улучшение (метод «душителя»: новое обрастает старое, пока старое не отомрёт), а не Большое Переписывание.

Бойскаутское правило

Работа с легаси не сводится к «не сломать». Есть стратегия постепенного улучшения, известная как бойскаутское правило: «оставляй код чуть чище, чем нашёл». Каждый раз, касаясь куска легаси по своей задаче, сделайте маленькое улучшение поблизости — переименуйте непонятную переменную, добавьте недостающий тест, разбейте слишком длинную функцию. По одному такому штриху на коммит — и за год база ощутимо оздоровляется без единого большого рискованного рефакторинга. Это противоположность «Большому Переписыванию»: улучшение размазано тонким слоем по обычной работе.

Для крупных переходов существует паттерн «душитель» (strangler fig): вместо того чтобы выключить старую систему и включить новую, вы постепенно перенаправляете отдельные куски функциональности на новую реализацию, пока старая не отомрёт сама. Так миграция идёт безопасными шагами, продукт всё это время живёт, и в любой момент можно откатиться. Этот подход — характерная черта зрелого инженера: он предпочитает серию обратимых маленьких шагов одному необратимому прыжку.

Частые ошибки

  • Пытаться понять всю базу разом. Понимай только путь своей задачи; остальное — по мере надобности.
  • Менять без страховочной сети. Изменение легаси без тестов — это игра в сапёра вслепую.
  • Мечтать о переписывании с нуля. Большой rewrite почти всегда дороже и рискованнее, чем кажется.

Итоги

  • Не нужно понимать всю базу — только путь своей задачи.
  • Перед изменением легаси фиксируйте текущее поведение тестами.
  • Улучшайте постепенно, мелкими безопасными PR.
  • Уважайте легаси: за хаосом обычно стоит утерянная логика, а не глупость.
Проверьте себя
1. Какой первый шаг при изменении непонятного легаси-кода?
AСразу переписать с нуля
BПокрыть текущее поведение характеризующими тестами как страховочной сетью
CУдалить всё, что неясно
DИгнорировать тесты для скорости
2. Почему «переписать всё с нуля» обычно плохая идея?
AЭто всегда быстрее
BRewrite недооценивает скрытую сложность и тысячи обработанных краёв в легаси
CТак запрещают правила Git
DНовый код не нуждается в тестах