14 промтов для рефакторинга legacy-кода: стратегии и примеры
Legacy-код — это не «плохой» код, а код, который уже приносит деньги и который страшно трогать. Он живет без тестов, с монолитными функциями и магическими числами. По данным исследования Stripe (2020), разработчики тратят около 17 часов в неделю на технический долг, а не на новые фичи. ИИ-ассистенты вроде ChatGPT и Claude могут взять на себя рутину анализа и преобразования, но только если вы дадите им точный контекст. В этой подборке — 14 промтов, которые я сам использую при работе с унаследованным кодом. Они покрывают весь цикл: от первичного анализа до миграции на современный стек.
Как работать с промтами
Прежде чем перейти к списку, запомните главное правило: промт должен быть контекстным. Не пишите просто «отрефактори этот код» — ИИ не знает, какие требования неизменны. Всегда добавляйте:
- Язык и версию (например, Java 8, Python 3.9)
- Фреймворк и библиотеки
- Ограничения (например, «не менять публичный API»)
- Что уже пробовали
Промты ниже — это шаблоны. Подставляйте свой код или опишите его словами, если вставить код нельзя (например, по соображениям безопасности).
Блок 1. Анализ и понимание
1. Промт для карты зависимостей
Задача: Понять, как модули связаны друг с другом, прежде чем что-то менять.
Промт:
Проанализируй следующий код и составь карту зависимостей: <код>.
Для каждой зависимости укажи:
- тип (вызов функции, импорт, глобальная переменная, событие)
- направление (кто от кого зависит)
- силу связи (высокая/средняя/низкая)
- насколько критична зависимость для работы системы
Выведи результат в виде таблицы в Markdown. Если код большой — сначала выдели ключевые модули.
Пример использования:
Скопируйте в промт файл контроллера на PHP (их любят legacy). ИИ вернет таблицу: Контроллер -> Сервис (высокая, вызовы) и подсветит, что контроллер тянет за собой всю базу данных.
2. Промт для поиска «божественных объектов»
Задача: Найти классы/функции, которые делают слишком много.
Промт:
Найди в этом коде «божественные объекты» — классы или функции, которые нарушают принцип единственной ответственности (SRP). Вот код: <код>.
Для каждого кандидата:
1. Подсчитай количество разных зон ответственности (например, работа с БД, логирование, валидация, отправка email).
2. Предложи декомпозицию: какие классы можно выделить.
3. Оцени риск: что сломается при рефакторинге.
Выведи в формате: <название>
| <признаки> | <риск> | <план>.
Пример:
На входе — класс OrderProcessor на 2000 строк с методами validate(), save(), sendConfirmation(). ИИ разобьет его на OrderValidator, OrderRepository, OrderNotifier и укажет, что метод save() не должен знать про отправку писем.
3. Промт для восстановления архитектуры по коду
Задача: Построить диаграмму архитектуры из спагетти-кода.
Промт:
Восстанови архитектуру приложения по следующему коду: <код>. Определи:
- слои (UI, домен, инфраструктура)
- паттерны (MVC, Repository, Adapter и т.п.)
- точки расширения и «запахи» (smells)
Нарисуй ASCII-диаграмму потоков данных, а затем опиши, как это можно преобразовать к чистой архитектуре (в духе Роберта Мартина).
Пример:
ИИ по коду на C# распознает скрытый Repository в кастомных SQL-запросах и предложит вынести их в отдельный интерфейс.
Блок 2. Стратегии рефакторинга
4. Промт для переименования (rename)
Задача: Избавиться от неинформативных имён переменных и функций.
Промт:
Переименуй все идентификаторы в этом коде, следуя правилам понятных имён из книги «Чистый код» Роберта Мартина: <код>.
Требования:
- имена должны отражать намерение (не `data`, а `customerList`)
- булевы переменные начинаются с is/has/can
- методы называют по действию (get, save, calculate)
- не меняй сигнатуры публичного API и JSON-поля
Выведи таблицу: старое имя -> новое имя -> причина изменения.
Пример:
Функция func1() станет calculateTotalPrice(), а переменная $d — $orderDiscount. ИИ объяснит замену, и вы сможете откатить изменения, если что-то пойдёт не так.
5. Промт для устранения дублирования (DRY)
Задача: Найти повторяющиеся фрагменты и объединить их.
Промт:
Найди дублирование кода в этом проекте: <код>. Для каждого дубля:
- определи степень копипасты (полное / частичное)
- предложи общий метод или утилиту
- оцени, сколько строк кода удастся удалить
- предупреди о возможных конфликтах (например, разные типы данных)
Отчёт в формате таблицы.
Пример:
В legacy-коде встречаются три одинаковых метода formatDate() в разных классах. ИИ предложит вынести в DateUtils и покажет, где ещё можно применить эту утилиту.
6. Промт для разбиения длинных функций
Задача: Разбить функцию на 200+ строк на маленькие куски.
Промт:
Разбей эту функцию на несколько меньших функций: <код>.
Условия:
- каждая новая функция выполняет одно действие
- не меняй логику и внешнее поведение
- используй «извлечение метода» (extract method) по Мартину Фаулеру
- сохрани имена параметров и порядок вызовов
Выведи новый код и список извлечённых методов с комментариями.
Пример:
Функция processOrder() на 300 строк разбивается на validateInput(), applyDiscount(), chargePayment(), notifyCustomer(). ИИ добавит комментарии, но их лучше переписать на человеческий язык.
7. Промт для замены «if-ок» на полиморфизм
Задача: Убрать длинные цепочки if/else или switch, используя стратегию или фабрику.
Промт:
Рефакторинг: замени цепочку if/else на полиморфизм. Вот код: <код>.
Создай иерархию классов, где каждая ветка становится отдельным классом. Не забудь:
- интерфейс/абстрактный класс с общим методом
- фабрику или DI, чтобы выбрать нужную реализацию
- YAGNI: не создавай лишних абстракций
Покажи новый код и старый код рядом.
Пример:
switch(type) для расчёта доставки превращается в интерфейс DeliveryStrategy с реализациями ExpressDelivery и Pickup.
8. Промт для удаления мёртвого кода
Задача: Найти неиспользуемые функции, переменные, импорты.
Промт:
Проанализируй код на наличие мёртвого кода: <код>.
Покажи:
- функции, которые нигде не вызываются
- переменные, которые вычисляются, но не используются
- импорты, которые не нужны
- закомментированные блоки, которые можно удалить
Для каждого пункта дай рекомендацию: удалить или оставить (если это часть контракта/рефлексии). Не удаляй ничего без моего подтверждения.
Пример:
ИИ найдет public function unusedMethod() и выделит её серым. Вы вручную удалите, но помните: если метод используется в рефлексии, он не «мёртвый».
9. Промт для инкапсуляции глобального состояния
Задача: Убрать глобальные переменные и синглтоны.
Промт:
В этом коде используются глобальные переменные: <код>. Для каждой глобальной переменной:
- найди все места чтения и записи
- определи, к какому модулю она относится
- предложи способ инкапсуляции: обычный объект, конфиг, сервис с DI
- оцени сложность миграции
Выведи план пошагово.
Пример:
Legacy-код на BadaBoom использует $GLOBALS['db']. ИИ предложит заменить на класс Database и передавать его в конструкторы. План: 1) создать класс, 2) заменить обращения, 3) убрать $GLOBALS.
Блок 3. Безопасность и тесты
10. Промт для генерации юнит-тестов перед рефакторингом
Задача: Написать тесты, которые зафиксируют текущее поведение, чтобы рефакторинг не сломал ничего.
Промт:
Сгенерируй юнит-тесты для кода: <код>.
Требования:
- используй фреймворк <JUnit/PHPUnit/pytest>
- протестируй все публичные методы
- для каждого метода добавь тесты: типичный случай, граничные значения, ошибки
- мокай все внешние вызовы (БД, HTTP)
- не проверяй внутреннюю реализацию
Выведи готовый код тестов.
Пример:
Для функции calculateDiscount(price, customerType) ИИ сгенерирует 5 тестов: обычный клиент, VIP, отрицательная цена, нулевая цена и null-customerType (с ошибкой). Это станет «защитной сеткой».
11. Промт для теории мутаций
Задача: Оценить качество существующих тестов.
Промт:
Оцени качество тестов для этого кода: <тесты> и <код>.
- Предложи 10 мутаций (намеренных ошибок) в коде.
- Определи, какие из них поймают тесты, а какие нет.
- Для непойманных мутаций объясни, какой сценарий пропущен.
Выведи таблицу: мутация
| поймана? | рекомендация.
Пример:
ИИ меняет if (a > 0) на if (a >= 0). Если тесты не упали, значит, нет проверки на нулевое значение. Метод «мутационное тестирование» описан в статье Пита Голда и др., но здесь ИИ делает грубую оценку.
12. Промт для выявления уязвимостей
Задача: Найти потенциальные дыры безопасности в legacy-коде.
Промт:
Проведи анализ безопасности этого кода: <код>.
Ищи:
- SQL-инъекции
- XSS
- небезопасную работу с файлами
- отсутствие валидации
- хардкод паролей и ключей
Для каждой проблемы: уровень риска (критический/высокий/средний), строка кода, эксплойт-сценарий и пример исправления.
Пример:
ИИ найдёт конкатенацию строк в SQL-запросе (например, "SELECT * FROM users WHERE id = " . $id) и предложит prepared statements. Ссылка на OWASP Top 10 будет уместна: https://owasp.org/Top10/
Блок 4. Миграция и модернизация
13. Промт для перехода со старого API на новый
Задача: Обновить код, использующий устаревшие методы библиотеки или фреймворка.
Промт:
Перепиши код так, чтобы он использовал новый API <библиотека>, вместо устаревшего: <код>.
- Источник: документация миграции (укажи ссылку, если есть)
- Сохрани поведение, но учти изменения в исключениях и типах
- Добавь комментарии, где логика изменилась
- Если устаревший метод удалён, предложи альтернативу
Выведи diff-стиль: старое -> новое.
Пример:
Обновление кода с PHP 5.6 на PHP 8.2: ИИ заменит ereg() на preg_match() или str_contains() и подскажет, что mysql_* больше нет.
14. Промт для конвертации с С на Go (или другого языка)
Задача: Переписать модуль на другой язык.
Промт:
Сконвертируй этот код с <С> на <Go/Python/Java>: <код>.
Учти:
- различия в управлении памятью (где это критично)
- идиоматику целевого языка (не портовый код, а естественный)
- обработку ошибок в стиле целевого языка
- не меняй алгоритм и интерфейс без необходимости
Покажи соответствие функций и библиотек в таблице.
Пример:
Код на PHP-функции array_map в Go превратится в цикл по срезу. ИИ подчеркнёт, что Go не имеет встроенного map, но добавит func mapSlice.
Заключение
Эти 14 промтов — не волшебная пилюля. Они работают, когда вы чётко формулируете контекст и проверяете результат. Помните: ИИ может ошибаться в логике, особенно в нестандартных edge-случаях. Всегда запускайте тесты и проводите code review. Начните с промта №1 и №10 — так вы получите карту кода и защитную сетку, а затем применяйте остальные.
Если хотите узнать больше о рефакторинге, прочитайте классику: «Рефакторинг» Мартина Фаулера (2019) и «Работа с legacy-кодом» Майкла Физерса (2004). А любую находку из наших промтов можно обсудить в комментариях к блогу.
Подписывайтесь на блог, чтобы не пропустить новые выпуски с эмпирическими исследованиями ИИ-помощи в поддержке старого кода.
Комментарии