Технический долг - неизбежная часть любой разработки. С течением времени даже хорошо написанный код может стать сложным для понимания и сопровождения. Часто разработчики, сталкиваясь с чужим или собственным кодом, испытывают отвращение - и только после проверки истории изменений гита понимают, что автором кода являлись они же.

Эта статья - не лекция. В интернете полно материалов про технический долг с графиками, квадратиками и теориями. Будем честны: большинство просто игнорирует его. Здесь мы попробуем посмотреть на технический долг так, как он есть на практике - как финансовый инструмент. Как кредитная карта с высоким процентом и мелким шрифтом: ею можно пользоваться, чтобы держаться на плаву, но потеря контроля проекту слишком дорого. Так и как же им управлять?

Если близка такая философия без розовых соплей, подпиcывайся на мой телеграм-канал. Там я регулярно делюсь подобными мыслями, разбираю сложные штуки простым языком и пощу мемы. Жду -> https://t.me/nullPointerDotEXE

Кредитная история одного проекта

Так вот техдолг не появляется за один день. Это медленный процесс, похожий на то, как человек постепенно влезает в кредитную кабалу. И происходит это по большей мере из-за скорости и человеческого фактора. Для простоты понимания приведу примеры с финансами, которые будут понятны каждому.

  • Этап 1: Первая кредитка - "Нам просто нужен MVP!"

Все начинается с невинного желания «быстро проверить гипотезу». Ты берешь свой первый кредит — хардкодишь конфиг, потому что некогда возиться с переменными окружения. Пишешь функцию на 150 строк, потому что «потом отрефакторим». Пропускаешь тесты, потому что «и так все работает».

В этот момент чувствуешь себя гением. Вот обогнал всех, выкатил фичу за два дня. Бизнес счастлив, тебе хлопают по плечу. Ты получил свою дозу дофамина и подсел на иглу быстрых, грязных решений.

  • Этап 2: Жизнь в долг - "Стабильность - признак мастерства"

Проект растет, а временные решения становятся постоянными. На тот самый захардкоженный конфиг уже завязано пять сервисов. Та самая функция на 150 строк обросла еще сотней строк костылей и теперь ее боятся трогать даже под угрозой увольнения.

Скорость разработки начинает падать. Чтобы добавить простую кнопку, нужно три дня изучать код и один день писать. Любое изменение вызывает цепную реакцию багов. Команда начинает говорить загадками: «Этот модуль лучше не трогать, он проклят». Новые фичи все еще пилятся, но уже за счет новых, еще более диких «кредитов».

  • Этап 3: Звонок от коллекторов - "Почему так долго?"

Наступает момент, когда проценты по долгу превышают все разумные пределы. Бизнес приходит с вопросом: "Раньше вы делали фичу за неделю, а теперь просите месяц на то, чтобы поменять текст. Что происходит?".

Это и есть звонок от коллекторов. Днище пробито. Команда больше не может брать в долг, потому что вся энергия уходит на обслуживание старых процентов. Она попросту выгорела, лучшие инженеры начинают смотреть по сторонам. Идея «давайте все перепишем с нуля» звучит все чаще.

А про момент с «переписать все с нуля» вообще ситуация максимально обманчивая. Это самый очевидный и самый провальный путь, о котором еще 20 лет назад писал Джоэл Спольски в своей статье «Things You Should Never Do».

Ипотека на архитектуру или микрозайм на костыль?

Хватит драмы. Давай разберемся, что не весь долг - зло. Как и в финансах, есть умные кредиты, а есть путь на дно.

Хороший долг - это осознанный технический компромисс.
Это не костыль от безысходности. Это взвешенное инженерное решение, принятое для достижения конкретной цели, с полным пониманием последствий и планом по их устранению.

  • Пример: Команда запускает новый сервис для обработки пользовательских фото. Нагрузка на старте ожидается небольшой - 100-200 юзеров в день. Чтобы запуститься через неделю, а не через три месяца, команда принимает осознанное решение не реализовывать сложную систему асинхронной обработки в очередях (типа RabbitMQ или Kafka) с последующей отдачей по SSE, а обрабатывать фото прямо в HTTP-запросе.

    • В чем долг? Они прекрасно понимают, что при росте нагрузки до 10 000 юзеров эта архитектура ляжет. Прямая обработка заблокирует веб-сервер при кучи открытых долгих хттп соединений и приведет к таймаутам. Это технически несовершенное решение.

    • Почему он "хороший"?

      1. Осознанный: Команда провела обсуждение и зафиксировала: "Мы идем на это, чтобы быстро проверить гипотезу. Мы знаем о рисках".

      2. Задокументированный: Сразу после принятия решения в создается таск "Внедрить асинхронную обработку фото", а в коде оставляется комментарий: //TODO: check PROJ-123.

      3. Есть триггер для погашения: Команда договаривается: "Как только мы достигаем 1000 активных юзеров в день или среднее время ответа превышает N времени, мы бросаем все и делаем задачу PROJ-123".

Это и есть ипотека. Вы сознательно берете упрощенную архитектуру сейчас, чтобы выиграть время, но у вас уже есть четкий план, как и когда вы будете ее "выплачивать".

«Плохой» долг — это микрозайм на костыль.
Это как раз те самые грязные, импульсивные решения, принятые в панике.

  • Пример: Разработчик пишет код, и у него не сходятся типы в его ЯП. Вместо того чтобы потратить 15 минут и разобраться, он пишет any, потому что дедлайн горит. Никто об этом не знает. Задача не заведена. Через полгода этот any прилетает в прод с ошибкой типов, и вся команда полночи ищет баг. Вот это - классический плохой долг. Он не дал никакой стратегической выгоды, только купил одному человеку 15 минут спокойствия.

Так что делать-то? План реабилитации

Неважно, как ваш проект оказался в текущей точке - создали ли вы осознано техдолг на архитектуру или погрязли в импульсивных костылях. Важно то, что в какой-то момент проценты по кредитам - и хорошим, и плохим - начинают душить.

Платежи в виде багов, долгого ревью, сложного онбординга новичков и бесконечных правок съедают все время, которое должно было идти на новые фичи. Скорость разработки падает, команда демотивирована, бизнес нервничает.

Это не повод впадать в депрессию и искать новую работу. Это повод составить план реабилитации. Вот три шага, которые помогут взять долг под контроль, пока он не взял под контроль вас.

Шаг 1: Перестаньте врать себе и начните считать
Первый шаг - это аудит. Нельзя управлять тем, что не измерено. Можно собрать команду (без менеджеров и продактов для начала) и провести некую инвентаризацию. Заведите страницу и выпишите все, что мешает.

Не надо оценивать в стори-пойнтах или часах, это утопия. Используйте простую шкалу насколько болит или влияет на разработку. Просто список:

  • Проблема: Модуль UserPermissions никто не понимает, любое изменение в нем ломает что-то в другом месте. Влияние: Высокое (блокирует разработку фич, связанных с ролями).

  • Проблема: Сборка фронтенда занимает 15 минут. Влияние: Среднее (раздражает, съедает время, но жить можно).

  • Проблема: Тестов на модуль оплаты нет вообще. Влияние: Критическое (страшно деплоить, цена ошибки - деньги).

Это будет ваша выписка. Болезненная, неприятная, но абсолютно необходимая. Теперь у вас есть предмет для разговора с бизнесом.

Шаг 2: налог на техдолг
Забудьте про "спринт рефакторинга". Это самообман, который никогда не сработает. Единственный рабочий механизм - это регулярный, обязательный рефакторинг.

Договоритесь с командой и, что важнее, продайте эту идею бизнесу, что 15-20% каждого спринта вы тратите на погашение долга из вашего списка. Не "если останется время", а железно. Это не время, которое вы не пилите фичи. Это время, которое вы покупаете для будущей скорости. Если бизнес ноет(как обычно и бывает), покажите им список из Шага 1 и задайте простой вопрос:

"Мы можем продолжать игнорировать это, но через полгода на любую фичу будет уходить в три раза больше времени. Нас это устраивает?".

Шаг 3: Станьте бойскаутом
Это правило должно быть выбито в стене над столом каждого разработчика:

"Оставь код чище, чем он был до тебя".

Это культура маленьких, атомарных улучшений, которая не требует отдельных тасков.

Залез в старый модуль, чтобы поправить баг? Стоит потратить лишние 20 минут.

  • Переименовать пару переменных с data и x на userProfile и order.

  • Разбить одну функцию на 300 строк.

  • Удали закомментированный код, который лежит там с 2016 года.

  • Добавь один несчастный тест на тот кейс, который ты только что чинил.

Но это не лекция по чистому коду. У меня есть статья касательно чистого кода, которая пропагандирует рациональную чистоту, а не слепое следование за Робертом Мартином.

Но это точно так же, как чистить зубы. Ты ведь не ждешь, пока они все выпадут, чтобы пойти к стоматологу. Ты делаешь это каждый день по чуть-чуть. Капля за каплей, и через год ты не узнаешь свой проект.

Вместо заключения

Не существует проектов без техдолга. Если в проекте его нет - скорее всего, либо проект никому не нужен и им никто не пользуется, либо он слишком простой.

Цель не в том, чтобы написать идеальный код. Идеальный код нахрен не нужен бизнесу. Бизнесу нужен работающий продукт, который приносит прибыль. Чистый код, масштабирование, архитектура и т.д. делается сугубо для инженеров и других инженеров, которые будут работать над проектом. Цель - найти баланс. Уметь брать хорошие долги, когда это оправдано, и не скатываться в штопор плохих на каждый пук.

Хватит относиться к техдолгу как к чему-то постыдному. Это просто переменная в уравнении разработки. И задача инженера - не игнорировать ее, а научиться ей управлять.

Я все. Гудлак!

Комментарии (2)


  1. user-book
    06.11.2025 19:21

    по моему я уже читал эту статью буквально на днях тут на хабре


  1. PoksPoks
    06.11.2025 19:21

    Идея норм, но без дисциплины быстро скатывается в хаос