Лет пять назад я воспринимал технический долг исключительно как проблему. Само слово «долг» давит: кажется, что ты кому-то должен, что нужно срочно взять кредит в виде спринта и героически всё переписать. Именно так мы и поступили на одном крупном проекте: выделили два месяца на рефакторинг ядра, отложили фичи, убедили бизнес, что так надо. Через два месяца код стал заметно красивее, а метрики продукта не сдвинулись ни на процент. Вот тогда я впервые задумался, правильно ли мы вообще считаем.
Перелом в голове случился, когда я начал смотреть на техдолг не как на минус, а как на актив. Звучит странно, но давайте честно: каждый кусок легаси, каждая кривая интеграция, каждый хак в отчётности — это накопленное знание о том, как продукт реально зарабатывает деньги. Мы когда-то сознательно выбрали эти решения ради скорости, и они до сих пор приносят выручку. Долг существует потому, что когда-то был выгоден. А значит, вопрос не в том, как погасить его целиком, а в том, какая часть сейчас работает на нас, а какая уже тормозит.
Простой пример из практики. У нас был модуль начисления бонусов, написанный четыре года назад на скорую руку. Выглядел он ужасно: метод на восемьсот строк, тестов почти нет. Команда предлагала переписать его целиком, оценка — месяц работы. Я попросил аналитиков посчитать, как часто мы вообще в него лазим и что он приносит. Оказалось, изменения вносились три раза за год, суммарно шесть дней правок. Переписывать за месяц — окупаемость в лучшем случае через два года. Мы оставили модуль в покое, только дописали тесты на критичные сценарии и добавили логирование.
С тех пор у меня появился рабочий подход, которым и хочу поделиться. Первое: перестать называть техдолг единой сущностью и разбить его на конкретные элементы. Не «плохой код в биллинге», а «отсутствие валидации в импорте платежей, из-за которого раз в месяц едут инциденты». Второе: к каждому элементу привязать цену — сколько часов в квартал он сжигает, сколько багов даёт, сколько времени теряют новички на онбординге. Третье: гасить долг там, где проценты самые высокие, а тело кредита самое дешёвое.
Активной стратегией я называю не бесконечный список задач на рефакторинг, а регулярный бюджет. Мы договорились с бизнесом примерно на десять-пятнадцать процентов ёмкости команды, которые каждый спринт уходят на здоровье кода. Не на большой рефакторинг мечты, а на то, что мешает прямо сейчас: убрать дублирующуюся логику, покрыть тестами место, где вчера уронили прод, ускорить медленный запрос. Выглядит не так героически, как глобальная переписка, зато бюджет не улетает в никуда.
Главная ошибка, которую я вижу у команд, — попытка заплатить весь долг сразу. Это как взять ипотеку и пытаться закрыть её за год, отказывая себе во всём. Обычно заканчивается выгоранием команды, замороженным продуктом и разочарованным бизнесом. Гораздо разумнее платить проценты: поддерживать систему в рабочем состоянии, чинить узкие места, а большие куски трогать только тогда, когда они реально мешают зарабатывать или несут риск.
Что посоветую читателям. Заведите простой реестр техдолга хотя бы в таблице: элемент, влияние на бизнес, примерная стоимость починки, приоритет. Раз в квартал пересматривайте его вместе с продуктом, а не только внутри команды. Не бойтесь сознательно решить, что какой-то долг вы платить не будете — это нормальное бизнес-решение. И самое важное: не превращайте качество кода в самоцель. Красивый код интересен нам, разработчикам, а деньги приносит работающий продукт.
В итоге за три года такого подхода мы сократили время на типовые доработки примерно вдвое и почти перестали устраивать аварийные спринты после релизов. При этом я так и не запустил тот самый большой рефакторинг, который когда-то казался единственным правильным выходом. Техдолг не исчез — он просто из неподъёмного груза превратился в управляемый инструмент. А как у вас в команде решают, что рефакторить, а что пусть живёт, и есть ли у вас регулярный бюджет на здоровье кода?
Перелом в голове случился, когда я начал смотреть на техдолг не как на минус, а как на актив. Звучит странно, но давайте честно: каждый кусок легаси, каждая кривая интеграция, каждый хак в отчётности — это накопленное знание о том, как продукт реально зарабатывает деньги. Мы когда-то сознательно выбрали эти решения ради скорости, и они до сих пор приносят выручку. Долг существует потому, что когда-то был выгоден. А значит, вопрос не в том, как погасить его целиком, а в том, какая часть сейчас работает на нас, а какая уже тормозит.
Простой пример из практики. У нас был модуль начисления бонусов, написанный четыре года назад на скорую руку. Выглядел он ужасно: метод на восемьсот строк, тестов почти нет. Команда предлагала переписать его целиком, оценка — месяц работы. Я попросил аналитиков посчитать, как часто мы вообще в него лазим и что он приносит. Оказалось, изменения вносились три раза за год, суммарно шесть дней правок. Переписывать за месяц — окупаемость в лучшем случае через два года. Мы оставили модуль в покое, только дописали тесты на критичные сценарии и добавили логирование.
С тех пор у меня появился рабочий подход, которым и хочу поделиться. Первое: перестать называть техдолг единой сущностью и разбить его на конкретные элементы. Не «плохой код в биллинге», а «отсутствие валидации в импорте платежей, из-за которого раз в месяц едут инциденты». Второе: к каждому элементу привязать цену — сколько часов в квартал он сжигает, сколько багов даёт, сколько времени теряют новички на онбординге. Третье: гасить долг там, где проценты самые высокие, а тело кредита самое дешёвое.
Активной стратегией я называю не бесконечный список задач на рефакторинг, а регулярный бюджет. Мы договорились с бизнесом примерно на десять-пятнадцать процентов ёмкости команды, которые каждый спринт уходят на здоровье кода. Не на большой рефакторинг мечты, а на то, что мешает прямо сейчас: убрать дублирующуюся логику, покрыть тестами место, где вчера уронили прод, ускорить медленный запрос. Выглядит не так героически, как глобальная переписка, зато бюджет не улетает в никуда.
Главная ошибка, которую я вижу у команд, — попытка заплатить весь долг сразу. Это как взять ипотеку и пытаться закрыть её за год, отказывая себе во всём. Обычно заканчивается выгоранием команды, замороженным продуктом и разочарованным бизнесом. Гораздо разумнее платить проценты: поддерживать систему в рабочем состоянии, чинить узкие места, а большие куски трогать только тогда, когда они реально мешают зарабатывать или несут риск.
Что посоветую читателям. Заведите простой реестр техдолга хотя бы в таблице: элемент, влияние на бизнес, примерная стоимость починки, приоритет. Раз в квартал пересматривайте его вместе с продуктом, а не только внутри команды. Не бойтесь сознательно решить, что какой-то долг вы платить не будете — это нормальное бизнес-решение. И самое важное: не превращайте качество кода в самоцель. Красивый код интересен нам, разработчикам, а деньги приносит работающий продукт.
В итоге за три года такого подхода мы сократили время на типовые доработки примерно вдвое и почти перестали устраивать аварийные спринты после релизов. При этом я так и не запустил тот самый большой рефакторинг, который когда-то казался единственным правильным выходом. Техдолг не исчез — он просто из неподъёмного груза превратился в управляемый инструмент. А как у вас в команде решают, что рефакторить, а что пусть живёт, и есть ли у вас регулярный бюджет на здоровье кода?