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