Як безпечно розібрати і спростити legacy-функцію

legacy-кодрефакторингтестидля початківців

Практичний підхід для розробника, який успадкував заплутану legacy-функцію і хоче спростити її без випадкової зміни поведінки

Як безпечно розібрати і спростити legacy-функцію

Уявіть звичайну задачу: ви відкриваєте функцію на 180 рядків, яка рахує знижку, форматує повідомлення, пише лог і ще тихо змінює поле в об’єкті. Вона працює роками. Її всі бояться чіпати. Але саме зараз треба додати маленьку зміну.

Найгірше, що можна зробити, — одразу попросити ШІ “перепиши красиво”. Legacy-код часто тримається на неочевидних правилах: старих граничних випадках, дивних місцях виклику, залежності від порядку операцій або поведінці, яку ніхто вже не пам’ятає. Хороший перший крок — не переписати функцію, а зрозуміти її і зафіксувати поточну поведінку.

Що таке legacy-функція

Legacy-функція — це не обов’язково поганий код. Це код, який уже має історію, використовується в продукті й може бути ризикованим для зміни. Часто він складний не тому, що автор писав недбало, а тому що функція довго накопичувала правила, винятки й швидкі виправлення.

Тому питання не в тому, як зробити її “гарною” за один раз. Питання в тому, як зменшити ризик і рухатися маленькими кроками.

Почніть з карти поведінки

Перед рефакторингом треба відповісти на кілька простих питань:

  • які дані функція отримує;
  • що вона повертає;
  • що вона змінює назовні;
  • які помилки або порожні значення обробляє;
  • хто її викликає;
  • які сценарії вже покриті тестами.

Це звучить повільно, але на практиці економить час. Якщо ШІ одразу пропонує нову версію коду, він може прибрати “дивну” умову, яка насправді захищає старий тариф, локаль або інтеграцію.

Де тут доречний ШІ

ШІ корисний як уважний помічник для читання коду. Його варто просити не “зроби рефакторинг”, а “поясни поведінку, знайди ризики, запропонуй тести-характеристики і тільки потім маленький патч”.

Саме тому промпт має змушувати модель спочатку думати про збереження поведінки. Якщо контексту бракує, нормальна відповідь ШІ — поставити питання, а не вигадати відсутні місця виклику.

Використайте промпт із блоку на сторінці, коли маєте перед собою конкретну функцію і можете вставити її код разом із мінімальним контекстом.

Безпечний порядок роботи

  1. Прочитайте функцію без змін і коротко опишіть її поведінку.
  2. Знайдіть входи, виходи, побічні ефекти й приховані залежності.
  3. Перевірте місця виклику, особливо якщо функція публічна або використовується в кількох модулях.
  4. Додайте тести-характеристики: вони фіксують те, як код поводиться зараз, навіть якщо ця поведінка неідеальна.
  5. Зробіть один маленький рефакторинг: наприклад, винесіть форматування, назвіть проміжне значення або розділіть чисту логіку й побічний ефект.
  6. Запустіть тести й порівняйте результат.
  7. Тільки після цього переходьте до наступного кроку.

Тест-характеристика не каже, що поведінка правильна з бізнес-погляду. Він каже: “ось що система робила до зміни”. Це корисно, коли ви ще не готові змінювати правила, але хочете зробити код зрозумілішим.

Типові помилки

  • Перейменувати змінні й одночасно змінити логіку.
  • Видалити умову, бо вона здається зайвою, не перевіривши історичні сценарії.
  • Ігнорувати побічні ефекти: логування, кеш, мутацію об’єкта, запит до API.
  • Рефакторити без тестів, а потім довіряти тільки візуальному огляду.
  • Просити ШІ зробити великий патч без обмеження на збереження поведінки.

Найбезпечніший рефакторинг часто виглядає скромно. Наприклад, ви не змінюєте алгоритм, а лише виносите перевірку isEligibleCustomer або окрему функцію для форматування повідомлення. Це маленький крок, але він робить наступний крок зрозумілішим.

Практичний наступний крок

Візьміть одну legacy-функцію, яку давно відкладаєте. Не починайте з переписування. Спочатку вставте її в промпт, попросіть карту поведінки й список тестів, а потім виберіть один найменший рефакторинг.

Мета не в тому, щоб перетворити старий код на ідеальний за вечір. Мета — зробити його трохи зрозумілішим і не втратити довіру до поведінки, на яку вже спирається продукт.

Короткий чеклист

  • Я можу пояснити функцію простими словами.
  • Я знаю її входи, виходи й побічні ефекти.
  • Я перевірив основні місця виклику.
  • Я додав або оновив тести для поточної поведінки.
  • Перший патч змінює структуру, а не бізнес-правила.
  • У мене є простий відкат: повернути маленький коміт або патч.

Розібрати і спростити legacy-функцію

Ти — досвідчений розробник, який допомагає безпечно рефакторити legacy-код. Мета: розібрати цю функцію, зберегти її поведінку і запропонувати мінімальні кроки спрощення. Ось функція: ```text [встав код функції] ``` Контекст: - мова/фреймворк: [вкажи] - відомі місця виклику: [вкажи або напиши "невідомі"] - наявні тести: [вкажи] - що я хочу покращити: [читабельність / дублювання / побічні ефекти / продуктивність] Спочатку не переписуй код. Дай відповідь у такому форматі: 1. Що функція робить простими словами. 2. Які входи, виходи, побічні ефекти й приховані залежності вона має. 3. Які граничні випадки треба зберегти. 4. Які тести або тести-характеристики треба додати перед змінами. 5. Який найменший перший рефакторинг можна зробити без зміни поведінки. 6. Який план відкату, якщо зміна зламає поведінку. Після цього запропонуй патч тільки для першого маленького кроку. Якщо бракує контексту, спочатку постав уточнювальні питання.