Вот давайте начистоту. Открываешь ты такой таск, видишь кусок кода, написанный полгода назад, и твоя первая мысль - "Господи, какой идиот это писал?". Потом git blame показывает твое имя. Классика. Этот момент, когда ты встречаешься со своим техническим долгом лицом к лицу.

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

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

Если тебе близка такая философия без розовых соплей, подписывайся на мой телеграм-канал. Там я регулярно делюсь подобными мыслями, разбираю сложные штуки простым языком и пощу мемы. Жду -> 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 task PROJ-123.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Переименуй пару переменных с data и x на userProfile и order.

  • Разбей одну функцию на 50 строк на три по 15.

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

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

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

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

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

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

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

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

Категорически рекомендую спросить себя после прочтения: мой техдолг - это актив, который помогает развивать проект быстрее, или это оковы на ногах, которые тянут весь проект на дно?

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

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


  1. Kerman
    04.11.2025 06:35

    о котором еще 20 лет назад писал Джоэл Спольски в своей статье "Things You Should Never Do".

    Ссылка выглядит так, как будто ведёт на joelonsoftware. А она ведёт на телеграмм-канал. Ну зачем так делать?


    1. Wowfirst
      04.11.2025 06:35

      Полностью согласен, вот тру ссылка:

      https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/


  1. YegorP
    04.11.2025 06:35

    Живо написано, но вообще-то более прямая аналогия прослеживается. Техдолг это, собственно, долг. Результат применения финансового инструмента, а не сам инструмент. Когда вы собираете мвп из палок и оно исправно всех обслуживает, то никакого долга ещё нет. Он, может, вообще не накопится если 100500 пользователей или фич так и не появятся в вашем сервисе. Или наоборот вы погрязнете в долгах с первой же секунды если переусложните решение на старте (ипотека на всю зарплату?).


  1. vkomp
    04.11.2025 06:35

    В целом согласен, но здесь как соринка в глаз:
    > Разбей одну функцию на 50 строк на три по 15.

    Важно, что последовательный код даже на 200 строк читается проще, чем дополнительные прыжки в функцию по клику. Просто крутишь мышью и читаешь как поэму. Ставишь точку дебага и смотришь что было раньше. Не надо вот функций на 15 строк!
    И замечаю, что сначала стараюсь разбить на функции - анализ же, а на следующей итерации собираю в общий пакет (уже причесаным кодом!) - синтез. И такое работает даже с повторно вызываем кодом - иногда лучше копипастить для читабельности.
    Второе, го с его обработкой ошибок раздувает простынь кода. На одну строку логики 1 или 3 строки err != nil. И 50 строк - это только разогреваешь кэш в голове, и последовательный код в одном месте - это добро.