Стратегія приборкання легасі: як безпечно рефакторити заплутаний код без зупинки бізнесу та зриву релізів
Кожен успішний проект, який прожив на ринку довше трьох років, неминуче обростає «технічним боргом»: тимчасовими милицями, написаними перед дедлайнами, не задокументованою бізнес-логікою та застарілими фреймворками. У певний момент будь-яка незначна зміна кнопки чи розрахунку тарифу починає ламати сусідні модулі, а розробники втомлено заявляють менеджменту: «Цей код неможливо підтримувати, треба все переписати з нуля».
Проте ідея «зупинити розробку нових фіч на пів року і переписати проект начисто» — це один із найнебезпечніших міфів у розробці софту, який у 80% випадків закінчується фінансовою катастрофою. Натомість досвідчені архітектори використовують прагматичну інженерну стратегію: поступову ізоляцію та заміщення старих компонентів на живій системі.
1. Чому «Rewrite from Scratch» майже завжди програє
Коли команда береться переписувати легасі на нову архітектуру з чистого аркуша, вона стикається з трьома неминучими пастками:
- Ілюзія знання бізнес-вимог: Старий заплутаний код містить сотні непомітних виправлень для крайніх випадків (Edge Cases), багів клієнтів та особливостей податкових звітів, про які давно забули навіть продакт-овнери. Переписуючи код наново, ви обов'язково втратите половину цих критичних нюансів.
- Ефект рухомої мішені (Moving Target): Поки інженери протягом року пишуть «нову ідеальну версію», бізнес не може зупинитися — він продовжує додавати нові функції у стару робочу систему. У результаті новий проект ніколи не може наздогнати старий за функціоналом.
- Ризик Big Bang релізу: Запуск абсолютно нової системи одномоментно в один день гарантує масовий шквал непередбачених падінь та відтік розлючених клієнтів.
Головне правило рефакторингу
Рефакторинг — це зміна внутрішньої структури програми, яка не змінює її зовнішньої поведінки. Якщо після ваших правок змінився формат відповіді API або поведінка інтерфейсу — це не рефакторинг, а переписування коду з внесенням регресій.
2. Патерн Strangler Fig: поступове задушення легасі
Архітектурний патерн «Фікус-душитель» базується на біологічній аналогії: рослина проростає навколо старого дерева, поступово обплітає його гілками і з часом повністю займає його місце, не даючи стовбуру впасти. В інженерії цей процес складається з трьох кроків:
- Встановлення маршрутизатора (Routing Facade). Перед старим додатком ставиться зворотний проксі-сервер (Nginx, Traefik або API Gateway). Усі 100% запитів користувачів спочатку проходять через нього і транслюються на старий моноліт.
- Виділення першого ізольованого домену. Обирається один невеликий, але цінний модуль (наприклад, сервіс авторизації або генерації PDF-звітів). Він реалізується за сучасними стандартами з чистим кодом і розгортається поруч на новому сервісі.
- Шар захисту від спотворень (Anti-Corruption Layer, ACL). Щоб новий модуль не отруївся кривими структурами даних старої бази, між ними будується адаптер. Він транслює застарілі об'єкти легасі у правильні доменні моделі нового коду.
- Перемикання маршруту та видалення старого коду. Маршрутизатор налаштовується так, щоб запити до цього конкретного модуля йшли на новий сервіс, а решта — на старий. Як тільки новий функціонал показав стабільність під навантаженням, стара реалізація всередині моноліту просто видаляється.
3. Як обґрунтувати рефакторинг перед керівництвом
Бізнес ніколи не виділить бюджет на абстрактну «красу архітектури» чи «чистий код». Технічні проблеми потрібно перекладати мовою бізнес-метрик:
- Час виходу на ринок (Lead Time for Changes): Покажіть, що через заплутаність коду запуск звичайної промо-акції або зміна поля у формі тепер займає 3 тижні замість 2 днів.
- Коефіцієнт збоїв релізів (Change Failure Rate): Зберіть статистику за квартал: скільки випусків нових версій призвели до екстрених відкатів (Rollbacks) чи падінь продакшну у робочі години.
- Швидкість онбордингу нових розробників: Скільки місяців потрібно новому інженеру з ринку, щоб зробити свій перший безпечний комміт у цей репозиторій.
Підсумок
Якісний софт — це не той, у якому взагалі немає технічного боргу, а той, чий борг залишається керованим. Прагматичний підхід до легасі полягає не в емоційному бажанні переписати все заново, а в методичній роботі за «правилом бойскаута»: залишати місце стоянки чистішим, ніж воно було до вашого приходу. Додаючи нову функцію, розплутуйте один вузол навколо неї — і система залишатиметься живою та прибутковою роками.