Содержание
Переписывать работающий проект с нуля стоит в редких случаях: когда технология умерла, архитектура не выдерживает новых требований, а кода немного. В остальных случаях надёжнее постепенный рефакторинг и замена системы по частям — паттерн «душитель» (strangler fig): новый код растёт вокруг старого и постепенно забирает его функции, при этом продукт продолжает работать и развиваться.
Разберём, почему переписывание часто проваливается, когда оно оправдано и как заменять систему постепенно.
Почему переписывание с нуля часто проваливается?
Переписывание выглядит заманчиво: старый код запутан, а новый будет чистым. Но старая система содержит годы исправлений и бизнес-правил, которые нигде не задокументированы, а пока команда переписывает, продукт стоит на месте или развивается в двух местах одновременно.
Типичные причины провала:
- скрытые требования — старый код обрабатывает десятки особых случаев, о которых никто не помнит;
- движущаяся цель — пока пишется новая версия, старая продолжает меняться;
- заморозка развития — бизнес полгода не получает новых функций;
- большой финальный переход — всё переключается разом, и ошибки проявляются у всех пользователей;
- недооценка — переписывание почти всегда занимает в несколько раз больше запланированного.
Когда переписывание всё же оправдано?
Переписывание оправдано, когда проект небольшой, технология больше не поддерживается или не позволяет решать задачи бизнеса, а постепенная замена обойдётся дороже. Решение стоит принимать после технического аудита, а не на эмоциях.
| Ситуация | Скорее рефакторинг | Скорее переписывание |
|---|---|---|
| Объём кода | Большой, годы работы | Небольшой, месяцы работы |
| Технология | Поддерживается, можно обновить | Мертва, нет специалистов и исправлений |
| Бизнес-логика | Сложная, много особых случаев | Простая, хорошо понятна |
| Требования к развитию | Нужны новые функции постоянно | Можно ненадолго заморозить |
| Тесты | Можно добавить | Добавить невозможно |
Как провести оценку — статья технический аудит продукта.
Фото: Unsplash
Как работает паттерн «душитель»?
Паттерн назван по растению-душителю, которое обвивает дерево и постепенно его заменяет. Перед старой системой ставится маршрутизатор — прокси или API-шлюз, — новые и переписанные функции реализуются в новой системе, а маршрутизатор направляет к ним запросы. Старая система постепенно теряет функции и в итоге отключается.
# Новая система уже обслуживает каталог и корзину, остальное — старая
location /api/catalog/ { proxy_pass http://new_app; }
location /api/cart/ { proxy_pass http://new_app; }
location / { proxy_pass http://legacy_app; }
Порядок действий:
- Поставить маршрутизатор перед старой системой без изменения поведения.
- Выбрать первый модуль — небольшой, ценный и слабо связанный с остальными.
- Реализовать его в новой системе, проверить на части трафика.
- Переключить маршрут, наблюдать за метриками, удалить старую реализацию.
- Повторять, пока старой системы не останется.
С чего начать рефакторинг?
Рефакторинг начинают с тестов, которые фиксируют текущее поведение: без них невозможно понять, сломалось ли что-то после изменений. Затем выбирают места, которые чаще всего меняются и чаще всего ломаются, — улучшение там даёт наибольший эффект.
- покройте критичные сценарии сквозными и интеграционными тестами — подробнее в статье какие автотесты нужны продукту;
- настройте мониторинг ошибок, чтобы видеть последствия изменений;
- обновите язык и фреймворк до поддерживаемых версий — статья обновление зависимостей;
- улучшайте код рядом с текущими задачами, а не отдельным огромным проектом;
- выделяйте на это постоянную долю времени команды.
Как не допустить новой «легаси» в будущем?
Код становится легаси не из-за возраста, а когда его боятся менять: нет тестов, никто не понимает, как он работает, а знания ушли вместе с авторами. Предотвратить это проще, чем исправлять.
- тесты на ключевые сценарии и CI на каждое изменение;
- регулярные обновления зависимостей;
- документация архитектурных решений и API;
- код-ревью и общие стандарты;
- явный учёт технического долга — подробнее в статье технический долг.
Если проект достался от другого подрядчика, сначала прочитайте статью как сменить подрядчика.
Коротко
- Полное переписывание часто проваливается из-за скрытых требований и заморозки развития.
- Оно оправдано для небольших проектов на мёртвой технологии.
- Паттерн «душитель» заменяет систему по частям через маршрутизатор.
- Рефакторинг начинают с тестов и мест, которые чаще всего меняются и ломаются.
- Чтобы не создать новое легаси, нужны тесты, обновления, документация и учёт долга.
Частые вопросы
Сколько времени займёт постепенная замена системы?
Обычно от нескольких месяцев до пары лет, но польза появляется сразу: каждый перенесённый модуль работает на новой основе. При переписывании с нуля польза появляется только в конце.
Можно ли продолжать развивать продукт во время рефакторинга?
Да, и это главное преимущество постепенного подхода. Обычно часть ресурсов команды выделяют на улучшение кода, а новые функции пишут сразу в новой части системы.
Как объяснить бизнесу необходимость рефакторинга?
Через бизнес-показатели: сколько времени уходит на типичную задачу, сколько ошибок после релизов, сколько стоит простой. Рефакторинг стоит связывать с конкретными целями, а не с красотой кода.



