Калькулятор процентов по техническому долгу: когда исправлять, когда терпеть для небольших команд
Технический долг — не чёрно-белое решение. Статья предлагает минимальную количественную основу, помогающую небольшим командам решить, какой долг платить, а какой продолжать нести.
Вопрос, который задаёт каждый разработчик
«Этот код ужасен. Надо рефакторить.»
Я слышал это десятки раз и сам говорил так же часто. Но со временем я заметил: после многих рефакторингов ожидаемого роста продуктивности не происходило. Вместо этого появлялись новые баги, проблемы совместимости и жалобы «раньше же работало».
Реальный вопрос: как объективно решить, исправлять беспорядок или жить с ним?
В небольших командах нет роскоши «20% каждого спринта на технический долг». Каждый час — это потраченные деньги.
Я разработал простой метод — называю его «Калькулятор процентов по техническому долгу».
Три ключевых показателя
Прежде всего: не весь долг плох. Многие системы выжили именно потому, что были запущены быстро. Опасность — не знать процентную ставку или точку взрыва.
Я смотрю на три вещи:
1. Множитель стоимости изменений
Отследите последние 5 модификаций модуля (исправления, новые функции, изменения конфигурации). Запишите «идеальное время» (если бы код был чистым и документированным) и «фактическое время».
Если фактическое время более чем в 3 раза превышает идеальное — долг стоит серьёзного внимания.
Пример: в парсере промптов для AI-инструмента были перемешаны три версии логики валидации. Каждый новый шаблон требовал полдня отладки. Множитель — 4,2x. После 1,5 дня унификации валидации следующие 10 изменений сэкономили в сумме более 6 дней.
2. Риск сбоев
Оцените, сколько инцидентов этот модуль может вызвать в ближайшие 3 месяца, если не трогать. Используйте прошлые данные: сколько было инцидентов за последние 3 месяца? Среднее время восстановления? Затронутые пользователи?
Перемножьте три числа — получите «балл риска». Спросите: если я потрачу X часов на рефакторинг, насколько снизится балл риска?
Если рефакторинг занимает 25 часов, а балл риска падает со 150 до 15, каждый балл обходится в 0,18 часа — эффективно. Если рефакторинг занимает 80 часов, каждый балл стоит 0,59 часа — лучше заняться другой работой.
3. Когнитивное трение в команде
Это сложнее всего количественно измерить, но оно сильнее всего вредит моральному духу. Считайте, сколько раз кто-то спрашивает «почему здесь так сделано?» или тратит дополнительное время на понимание скрытых правил.
Отмечайте каждый такой вопрос. Если более 3 раз на один модуль без документации — долг нужно погашать.
Квадрант решений
Упростим до двух измерений: частота изменений (высокая/низкая) и серьёзность последствий (высокая/низкая).
- Высокая частота + высокая серьёзность: рефакторинг как можно скорее. Это опухоль.
- Высокая частота + низкая серьёзность: локальная оптимизация, не полная переписка. Исправьте только горячий путь.
- Низкая частота + высокая серьёзность: добавьте защитный код (assertions, логи, предохранители) вместо глубокого рефакторинга.
- Низкая частота + низкая серьёзность: не трогайте. Приведите в порядок при следующем касании, не создавайте отдельный проект.
Гипотетический случай
Поддержка модуля синхронизации словаря в приложении для изучения языка. Написан наспех год назад, без юнит-тестов, миграции БД вручную. 6 изменений за 3 месяца, каждое занимало на 2 часа больше из-за отладки синхронизации. Два инцидента с потерей данных пользователей (восстановлено, но были жалобы). Новому разработчику потребовалось два дня, чтобы решиться его трогать.
Множитель стоимости >3x, балл риска = 2 инцидента × 3 часа восстановления × 50 пользователей = 300, когнитивное трение — 4 вопроса.
Это высокая частота + высокая серьёзность. Рекомендую 3–5 дней на переписывание модуля с автотестами и скриптами миграции. Ожидаемая окупаемость: 2 часа экономии на каждом будущем изменении, предотвращение 2 инцидентов за квартал, устранение когнитивных затрат.
Когда НЕ надо рефакторить
Бывает, модуль трогают раз в год. Код грязный, но лишнее время — всего 2 часа в год. Тратить 2 дня на рефакторинг — невыгодно.
Хуже: рефакторинг сам по себе несёт риски. Я видел, как небольшая команда потратила 2 месяца на переписывание админки — в это время отдел продаж не мог менять правила CRM, потеряли сделки. Прибыль от этих сделок могла бы нанять человека для поддержки старого кода.
Не рефакторьте ради чистоты кода; рефакторьте из-за бизнес-боли. Это перекликается с моей предыдущей статьёй об эволюции архитектуры, но сегодня мы сосредоточены на экстренной оценке одного модуля.
Практический чек-лист для небольших команд
- Выберите самый проблемный модуль.
- Соберите количество изменений и лишнее время из Git-лога и табелей (за последние 3 месяца).
- Перечислите инциденты: количество, время восстановления, затронутые пользователи.
- Запишите, сколько раз члены команды задавали вопросы по модулю за последний месяц.
- Оцените усилия на рефакторинг (будьте пессимистичны, умножьте на 1,5).
- Используйте балл риска и множитель стоимости для решения.
- Решите: рефакторинг, локальная оптимизация, добавление защиты или отметка «исправить при следующем касании».
- Если рефакторинг, определите критерии завершения: «После рефакторинга трудозатраты на аналогичное изменение должны быть ниже X часов; частота инцидентов ниже Y.»
Последнее слово
Технический долг — не моральная проблема. Это экономическое решение. Не все команды, имеющие долг, умирают. Но те, кто плохо считает, — да.
PaxLee