Технический долг и рефакторинг простыми словами: за что платит заказчик, когда «ничего не меняется»
Короткий ответ: технический долг — это упрощения в коде, которые ускорили запуск, но делают каждую следующую правку дольше и дороже. Рефакторинг — работа по наведению порядка внутри кода без изменения того, что видит пользователь. Заказчик платит за него не ради «красоты», а чтобы доработки снова занимали дни, а не недели. Но рефакторинг оправдан только там, где код часто меняют.
Ниже — как отличить реальный долг от предлога, сколько времени на него разумно закладывать и какие вопросы задать подрядчику, чтобы не платить за бесконечную «оптимизацию» без понятного результата.
Что такое технический долг?
Это разница между тем, как код устроен сейчас, и тем, как он должен быть устроен, чтобы его было легко менять. Как с кредитом: вы получили скорость сегодня, а «проценты» платите потом — лишними часами на каждую доработку.
Метафору придумал программист Уорд Каннингем в начале 1990-х. Мартин Фаулер в своей статье о техническом долге разбирает её на пример: функция в аккуратном коде занимает четыре дня, а в запутанном — шесть. Два лишних дня — это проценты. Наведение порядка, которое займёт пять дней, — это основной долг. Ради одной функции уборка не окупится: девять дней вместо шести. Но если в этом месте предстоит ещё несколько похожих доработок, выгоднее сначала погасить долг.
Важная деталь: проценты платятся только там, где код трогают. Запутанный модуль, который годами работает и никто его не меняет, денег почти не стоит. Поэтому разговор о долге — всегда разговор о том, какие части продукта вы собираетесь развивать.
Откуда он берётся даже у хороших команд?
Из нормальной жизни проекта: срочных запусков, временных решений, которые стали постоянными, смены требований и старения библиотек. Нулевого долга не бывает. Бывает долг осознанный и записанный — и долг, о котором никто не знает.
- Срочный релиз. Акция стартует в понедельник, и форму заказа делают «пока так», без проверки редких случаев. Решение правильное — если потом к нему вернулись.
- Временное решение. Обмен с учётной системой через выгрузку файла «на месяц, пока не будет API». Через два года файл всё ещё ходит, а вокруг него выросли три обработчика.
- Изменившиеся требования. Сервис строили под одного менеджера, теперь их двадцать, и права доступа приклеены сбоку к коду, который о ролях не знал.
- Старение зависимостей. Код не менялся, а мир изменился. Например, у PHP каждая ветка получает два года активной поддержки и ещё два года только исправлений безопасности; ветка 8.2 по графику на php.net получает их до 31 декабря 2026 года, а более старые уже не получают. Сайт на такой версии работает, но обновлять его со временем всё дороже.
- Смена людей. Автор решения ушёл, пояснений не оставил. Следующий разработчик боится трогать непонятное и пишет рядом своё — так появляется дублирование.
- Экономия на тестах. Без автоматических проверок любое изменение приходится проверять руками, и со временем команда начинает избегать изменений вообще.
Осознанный долг — нормальный инструмент. Если вам нужно проверить спрос за две недели, имеет смысл сознательно упростить внутреннее устройство. Главное — записать, что именно упростили, и договориться, когда к этому вернуться.
Как понять, что долг уже мешает бизнесу?
По деньгам и срокам, а не по словам разработчика. Если похожие правки год назад занимали день, а сейчас неделю, если после каждой выкладки всплывают ошибки в соседних разделах и новый человек долго входит в проект, долг уже стоит вам денег.
Заказчику не нужно читать код, чтобы заметить проблему. Достаточно вести простую статистику по задачам: сколько стоила оценка, сколько ушло по факту, сколько ошибок нашли после выкладки. Если задачи ведутся на доске, эти цифры видны без отдельного отчёта.
Один симптом сам по себе ничего не доказывает: долгая оценка бывает и у сложной задачи. Тревожный знак — когда несколько симптомов совпадают и тенденция месяцами идёт в одну сторону. Ниже — частые симптомы и вопросы, которые помогают понять причину.
| Симптом | Что обычно стоит за ним | Что спросить у разработчика |
|---|---|---|
| Мелкая правка оценивается в несколько дней | Одна и та же логика скопирована в разные места, менять приходится везде | Где ещё живёт эта логика и почему её нельзя поменять в одном месте? |
| После правки ломается то, чего не трогали | Части системы сильно связаны, автотестов нет или мало | Какие проверки запускаются перед выкладкой и что они покрывают? |
| Ошибки появляются «из ниоткуда» после обновления сервера | Устаревшие версии языка, фреймворка или библиотек | Какие версии стоят сейчас и до какой даты они получают исправления безопасности? |
| Новый разработчик неделю «входит в проект» | Нет описания запуска, схемы данных, история изменений без пояснений | Есть ли инструкция, по которой проект поднимается с нуля за день? |
| Выкладка — это событие, к ней готовятся вечером в пятницу | Ручной перенос файлов, нет отката на прошлую версию | Как откатить неудачную выкладку и сколько это займёт? |
| Оценки сроков всё время «плывут» вверх | Разработчик сам не уверен, что заденет правка | Какая часть оценки — сама задача, а какая — разбор старого кода? |
Что такое рефакторинг и чем он отличается от переписывания?
Рефакторинг — это изменение внутреннего устройства кода без изменения его поведения: пользователь ничего не замечает, а разработчику становится проще вносить правки. Переписывание — создание системы заново, часто на другой технологии. Это разные по риску и цене работы.
Классическое определение дано на refactoring.com: изменение внутренней структуры программы, которое делает её понятнее и дешевле в доработке, не меняя наблюдаемого поведения. На практике хороший рефакторинг идёт маленькими шагами: после каждого шага система работает и её можно выложить.
Примеры того, что делают при рефакторинге:
- сводят скопированную в пять мест логику расчёта цены в одно место;
- разделяют огромный файл на понятные части по смыслу;
- дают переменным и функциям понятные имена;
- добавляют автотесты на важные сценарии перед тем, как их менять;
- убирают код, который давно не вызывается.
Переписывание с нуля соблазнительно, но рискованно. В старом коде спрятаны годы исправлений редких случаев, о которых никто не помнит: особый расчёт для одного клиента, обработка сбоя платёжной системы. При переписывании их теряют и находят заново уже на живых пользователях. Как решать вопрос «доработать или переписать» при смене исполнителя, мы разбирали в статье о смене разработчика и аудите чужого кода; здесь же речь о долге в продукте, который вы продолжаете развивать с той же командой. Чем рефакторинг отличается от обновления зависимостей и переписывания — в таблице.
| Рефакторинг | Обновление зависимостей | Переписывание | |
|---|---|---|---|
| Что меняется | Внутреннее устройство кода, поведение для пользователя — нет | Версии языка, фреймворка, библиотек | Почти всё: код, часто схема данных и интерфейс |
| Масштаб | Небольшие шаги рядом с текущими задачами | От часов до недель, зависит от отставания | Отдельный проект со своими сроками |
| Риск для работающего продукта | Низкий при тестах и маленьких шагах | Средний: меняется поведение библиотек | Высокий: две системы, перенос данных, забытые сценарии |
| Когда уместно | Код меняют часто, и каждая правка идёт тяжело | Версии выходят из поддержки или мешают новым функциям | Технология мертва или задачи бизнеса сменились целиком |
Сколько времени закладывать на долг?
Жёсткой нормы нет. Рабочий подход — постоянная небольшая доля в каждом цикле работ плюс правило: перед крупной доработкой привести в порядок именно тот участок кода, который она затронет. Доля должна быть видна в плане, а не прятаться внутри оценок.
Как это выглядит на практике:
- Реестр долга. Разработчик ведёт список: что упрощено, где, чем грозит, сколько примерно стоит исправить. Это обычные задачи на доске, а не устные жалобы.
- Доля в плане. В каждом месяце или спринте часть задач — из этого реестра. Заказчик видит их наравне с новыми функциями и может спросить, зачем каждая.
- Правило «оставь чище, чем было». Если правка затрагивает запутанный участок, его немного приводят в порядок в рамках той же задачи и пишут об этом в описании.
- Плановые обновления. Раз в квартал проверяют версии языка, фреймворка и библиотек и сроки их поддержки. Обновлять понемногу дешевле, чем раз в пять лет прыгать через несколько версий.
- Отдельный этап — только по поводу. Крупный рефакторинг выделяют в отдельную работу, когда впереди большая доработка именно этой части или технология выходит из поддержки.
Если продукт живёт на поддержке, долг удобно гасить в её рамках. Поддержка у нас стоит от 7 900 ₽ в месяц, состав считаем после разбора проекта; подробно, что в неё входит, — на странице поддержки и развития. Для нового проекта стоит заранее договориться, что внутреннее качество тоже входит в результат: описание запуска, понятная структура, автотесты на ключевые сценарии. Как это вписывается в жизненный цикл продукта, мы описали в статье об этапах разработки.
Какие вопросы задать подрядчику?
Такие, на которые есть проверяемый ответ: что именно изменится, как вы это заметите и как поймёте, что работа закончена. Если подрядчик не может связать рефакторинг с конкретными будущими задачами, бюджет на него легко превращается в бесконечный.
- Какие доработки станут быстрее после этой работы? Хороший ответ называет конкретные функции из вашего плана.
- Как проверить, что ничего не сломалось? Ответ — автотесты, сценарии ручной проверки, выкладка по частям. «Мы аккуратно» — не ответ.
- Можно ли делать это по частям? Работа, которую нельзя разбить на шаги и выкладывать понемногу, рискованна сама по себе.
- Что будет, если не делать? Честный ответ иногда звучит как «ничего страшного, пока этот модуль не трогаем».
- Какие версии языка и библиотек стоят и до какой даты они поддерживаются? Ответ должен быть в виде списка с датами, а не «всё актуально».
- Где записан долг? Если реестра нет, попросите его составить — это несколько часов работы, и он пригодится любой команде.
- Где лежит код и есть ли у меня к нему доступ? Без доступа к репозиторию вы не сможете ни проверить работу, ни передать проект. Что там смотреть — в статье о репозитории кода для заказчика.
Отдельно о договоре. По нашему договору гарантия — 30 календарных дней с даты акта: в это время мы бесплатно устраняем ошибки и дефекты результата, возникшие по нашей вине. Технический долг под гарантию обычно не подпадает: функции работают, вопрос в том, как легко их менять. Поэтому его планируют как обычные задачи поддержки или развития.
Когда рефакторинг не нужен
Когда код почти не меняется, продукт скоро заменят или вы ещё проверяете спрос. В этих случаях деньги на наведение порядка не вернутся: проценты по долгу платятся только там, где идут доработки.
- Стабильный участок. Модуль работает, правок в нём не планируется. Пусть остаётся как есть, даже если код в нём некрасивый.
- Продукт на замену. Если через полгода систему заменят, вкладываться в её внутреннее устройство бессмысленно — кроме обновлений безопасности.
- Проверка гипотезы. На этапе первой версии скорость важнее чистоты. Долг можно брать сознательно, записав, что упростили.
- Рефакторинг «вообще». Если на вопрос «какие задачи станут быстрее» нет ответа, это не план работ, а пожелание разработчика сделать красиво.
Типичные ошибки заказчиков и команд:
- годами не выделять на долг ни часа, а потом получить счёт за большое переписывание;
- соглашаться на «перепишем всё с нуля» без описания, как перенесут данные и редкие сценарии;
- смешивать рефакторинг и новые функции в одной большой задаче — потом невозможно понять, что сломало систему;
- оценивать работу по «красоте кода», а не по срокам последующих доработок и числу ошибок;
- обновлять библиотеки только тогда, когда хостинг отключил старую версию и сайт уже не работает.
Если доработки у вас стали заметно дольше и вы не понимаете, почему, начните с разбора: какие части продукта вы развиваете, какой долг в них накопился и что из него стоит гасить. Мы делаем это в рамках заказной разработки и поддержки, а цены на типовые работы есть в прайсе.
Короткие ответы на частые вопросы
Технический долг — это значит, что разработчик сделал плохо?
Не обязательно. Долг появляется и у сильных команд: из-за срочных релизов, смены требований и того, что библиотеки стареют сами. Плохо, когда о долге молчат и не планируют время на его погашение.
Входит ли устранение технического долга в гарантию?
Гарантия по договору — 30 календарных дней с даты акта — касается ошибок и дефектов результата, возникших по вине исполнителя. Технический долг — это внутреннее качество кода при работающих функциях, поэтому его обычно планируют как отдельные задачи поддержки или развития.
Что такое легаси-код?
Так называют старый код, который работает и приносит пользу, но его тяжело и страшно менять: автор ушёл, документации нет, технологии устарели. Легаси — не приговор, его можно постепенно приводить в порядок.
Можно ли проверить технический долг без программиста?
Отчасти. Следите за сроками типовых правок, числом ошибок после выкладок и временем, которое нужно новому человеку на вход. Если эти цифры растут при неизменной команде, долг копится.
Сколько стоит рефакторинг?
Отдельной цены у рефакторинга нет: он зависит от объёма кода и того, какие части меняются чаще. Удобно встраивать его в поддержку — у нас она стоит от 7 900 ₽ в месяц, точный состав считаем после разбора проекта.
Услуги и кейсы по теме: поддержка сайта от 7 900 ₽/мес · заказная разработка · цены и сроки
Расскажите, какие доработки у вас стали долгими и дорогими, — посмотрим проект и честно скажем, где нужен рефакторинг, а где он не окупит себя.
Рассчитать проект →Оценку срока и цены по брифу делаем бесплатно, обычно отвечаем в течение часа в рабочее время. Типовой договор — посмотреть до оплаты.
