Технический долг: почему код гниёт и как с этим жить
Проект начинался красиво. Чистая архитектура, понятный код!
Через два года — легаси. Новые разработчики боятся трогать. Баги появляются от любых изменений. Фичи, которые раньше делались за день, занимают неделю.
Как это произошло? Постепенно. По чуть-чуть. Незаметно.
Что такое технический долг
Метафора Уорда Каннингема. Некачественный код — это долг. Вы берёте в кредит у будущего.
Быстрое решение сейчас — проценты потом. Проценты — замедление разработки, баги, сложность изменений.
Как финансовый долг: иногда оправдан, иногда необходим. Но если не платить — накапливается.
Виды технического долга
Осознанный стратегический. «Мы знаем, что это хак. Но нужно выпустить до дедлайна. Вернёмся и исправим». Иногда оправдан. Проблема — часто не возвращаются.
Осознанный тактический. «Сделаю по-быстрому, работает же». Разработчик знает, что срезает углы. Выбирает так.
Неосознанный. Разработчик не знал лучшего способа. Сделал как умел. Через год приходит более опытный — видит проблемы.
Устаревание. Код был хорош в своё время. Технологии изменились. Подходы устарели. Код стал долгом без вины автора.
Как накапливается
Каждый компромисс маленький. «Это всего один хак». «Потом отрефакторим». «Сейчас нет времени».
Но компромиссы суммируются. Один хак ссылается на другой. Обходные решения переплетаются. Появляются «заколдованные» места, которые нельзя трогать.
Новые разработчики приходят, не понимают код. Боятся менять. Добавляют обходные решения поверх. Долг растёт.
Это экспоненциальный процесс. Чем больше долг — тем сложнее добавлять фичи — тем больше давление срезать углы — тем больше долг.
Как выглядит на практике
Изменение в одном месте ломает другое. Связи неочевидны, зависимости скрыты.
Дублирование. Одна логика в пяти местах. Исправил в одном — забыл в четырёх.
Тесты, которые ничего не тестируют. Или тестов нет. Каждое изменение — лотерея.
Документация не соответствует коду. Или документации нет.
Новый разработчик выходит на продуктивность месяцами. Код непонятен, знания в головах тех, кто уволился.
Почему игнорируют
Не видно бизнесу. Технический долг не отображается в отчётах. Клиенты не жалуются на архитектуру. Пока фичи выходят — кажется, что всё хорошо.
Сложно измерить. Сколько стоит технический долг? Точно не посчитать. «Фичи замедлились» — но может, и другие причины.
Давление бизнеса. «Нам нужна фича, а не рефакторинг». Рефакторинг не приносит денег сейчас. Фича — приносит. Выбор очевиден.
Смена команды. Те, кто создал долг — ушли. Новые разбираются. Винить некого, историю не знают.
Как платить по долгу
Бойскаутское правило. Оставляй код чище, чем нашёл. Не отдельная задача на рефакторинг. Каждая задача — немного рефакторинга.
Работает с умеренным долгом. С критическим — недостаточно.
Выделенное время. 20% времени на технические улучшения. Не когда-нибудь — регулярно, в каждом спринте.
Крупный рефакторинг. Иногда накопилось столько, что нужен проект. Неделя, месяц, квартал — переработка модуля, системы.
Рискованно. Бизнес теряет терпение. Можно сломать работающее. Нужны тесты, которых может не быть.
Переписывание. Иногда дешевле написать заново, чем разгребать.
Как предотвращать
Code review. Не формальный «посмотрел, апрув». Реальное обсуждение. Вопрос «почему так?» должен быть нормой.
Стандарты кода. Автоматизированные где возможно. Линтеры, форматтеры. Не дискуссия о табах и пробелах — автоформат.
Тесты. Код с тестами рефакторить безопасно. Код без тестов — страшно. Страх ведёт к избеганию, избегание — к накоплению долга.
Документация решений. Почему выбрали это решение. Какие альтернативы рассматривали. ADR — Architecture Decision Records.
Культура качества. Сверху. Если менеджмент давит «быстрее-быстрее», качество невозможно. Если качество — ценность, оно будет.
Разговор с бизнесом
Технический долг — не технический термин. Это бизнес-риск.
Переведите на язык денег. «Из-за состояния кода фичи занимают вдвое больше времени. Это вдвое больше зарплат разработчиков. Или вдвое меньше фичей за квартал».
«Количество багов растёт. Если ляжет продакшен — потери X рублей в час».
«Новые разработчики выходят на скорость за три месяца вместо одного. Это три месяца зарплаты без полной отдачи».
Цифры примерные. Но порядок понятен.
Итоговая мысль
Технический долг неизбежен. Вопрос — управляемый он или вышедший из-под контроля.
Маленькие компромиссы суммируются в большие проблемы. Это занимает годы, поэтому незаметно.
Платите регулярно — небольшими частями. Не накапливайте до катастрофы.
Код — это не статичный артефакт. Это живая система, требующая ухода.
Относитесь к нему как к саду, не как к зданию. Сад требует постоянного внимания. Здание — до следующего капремонта.
Капремонт кода — дорого и больно. Регулярная прополка — дёшево и устойчиво.