Как не позволить техническому долгу одолеть вас

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

fd8cf8afe2bcd55c30ef3297f95b7382.jpg

Технический долг — популярный термин у айтишников. Если максимально обще выражаться, под этим словосочетанием понимают использование неоптимальных решений для ускорения процесса разработки. Почему он называется именно «техническим долгом», а не просто «хламом»? Потому что он отчасти похож на финансовый долг: если мы не возвращаем его, это сказывается на новых функциях и даже обслуживании, точно так же, как проценты накапливаются по вашей задолженности.

Одной из причин возникновения технического долга являются сознательные и бессознательные компромиссы при проектировании и создании систем, отсутствие чистого кода, документации и «best practices». Есть и другая причина: технологии развиваются, и то, что было идеальным решением два года назад, уже не так удачно смотрится сегодня.

Мифы двух бэклогов

Некоторые команды зачем-то ведут два бэклога: один ориентирован на продукт, второй — на технологии. Это неразумно, и вот почему:

  • Трудно установить перекрёстный приоритет в отдельных невыполненных задачах из этих бэклогов;

  • Такой подход подпитывает мышление «мы против них», что убивает сплоченность команды и мешает общим целям;

  • Расстановка приоритетов определяется всей командой. Исключение представителей продукта — нерационально;

  • Усложняется планирование спринта, если нет строгих правил распределения ресурсов (например, 20% времени постоянно выделено на технический долг);

Рекомендую иметь один бэклог и добавлять туда все ваши задачи. Помечайте технический долг, если вам нужна статистика, но добейтесь того, чтобы приоритеты были расставлены по всем невыполненным задачам.

Не превращайте технический долг в игру «обвини другого»

Очень часто встречающаяся ошибка: обвинение всех вокруг в возникновении технического долга. Наверняка вы видели, как некоторые сотрудники (инженеры, продакт-менеджеры) говорили коллегам что-то вроде «Если бы вы сразу придумали лучшее решение, то эта ситуация не возникла бы». Это глупые, нечестные и бессмысленные обвинения.

Идеал недостижим. Мы — люди, контекст постоянно меняется, технологии развиваются. Это надо просто принять. Лучшее, что могут сделать разработчики и иже с ними — это учиться на своих ошибках, внедрять передовой опыт и максимально полно осознавать компромиссы, на которые идут при разработке продукта.

Игры в обвинения отвлекают всех от решения проблемы. Люди вынуждены защищаться, что снова приводит к «перебрасыванию мяча» друг к дружке, ни на шаг не приближая нас к действительно важному результату.

Как обсуждать технический долг

Мы обсудили основные ошибки, а теперь давайте поговорим о том, как правильно аргументировать важность погашения технического долга. Обычно это сводится к перечислению рисков, вызванных существующим техническим долгом, сложностью обслуживания и поддержки, а также, упором на то, что он препятствует разработке новых функций.

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

Лучшая стратегия здесь: говорить на языке, понятном собеседнику. Просто говорить о важности бессмысленно, ведь в бэклоге может находиться ещё 100500 задач, которые тоже кажутся важными. Не говорите, что хотите заняться техдолгом просто так, «по фану». Если ваши аргументы выглядят как желание поиграться с любимым проектом, вашу инициативу вряд ли одобрят.

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

Риски

e38b2f6a5eaf6ed920485d9fd57ebe76.jpg

К некоторой части технического долга прилагаются и риски. Например, если ваше решение использует стороннюю библиотеку, срок службы которой подходит к концу — это риск. Если вы не обновите решение или не перейдёте на другое, более совершенное, то ваша система, зависящая от третьей стороны, может превратиться в тыкву, став нефункциональным. Или станет уязвимым из-за отсутствия новых исправлений безопасности. Разумеется, ситуации могут быть разными. Надо различать уровни угрозы: отключение систем на следующей неделе или вероятность эксплуатации какой-либо уязвимости через пару лет.

Другой риск связан с удержанием клиентов. Плохой опыт, вызванный не самыми лучшими решениями (недовольство частыми отключениями, медленном обслуживании и прочими «мелочами») приводит к оттоку клиентов.

Ещё несколько аргументов, которые можно использовать при обсуждении рисков технического долга:

  • Мы можем исправить две ошибки, но пропустим третью из-за «дублирования кода».

  • Текущая архитектура системы может замедлить работу пользователей при высоких нагрузках.

  • Отсутствие современных решений по безопасности может привести к возникновению инцидентов и юридической ответственности;

  • Существует вероятность появления новых ошибок из-за отсутствия юнит-тестов;

  • Сложность и негибкость кодовой базы заставляют отказываться от новых функций из-за чрезмерных трудозатрат на их разработку.

Чтобы сделать вашу речь о необходимости заняться техническим долгом более убедительной, соберите данные о вашей инфраструктуре и назовите имеющиеся проблемы. Да, это не всегда возможно. Но с конкретными аргументами вы имеете больше шансов на принятие желаемого решения. Помните, что аргументом в вашу пользу может стать даже слишком долгое время выполнения тестов, ведь это время вы вынужденно простаиваете.

Трудности обслуживания

Сизиф борется с техническим долгомСизиф борется с техническим долгом

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

Ну правда, сначала часа четыре уйдёт на то, чтобы понять, что происходит в системе. Ещё часа два — на то, чтобы сделать тесты зелёными. А потом час разворачивать исправления, так как система при обновлении зависает 3 раза из 5.

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

Мои примеры можно назвать забавными, но они помогают лучше понять, как много времени можно сэкономить, если всё будет работать должным образом. Поговорите со своей командой о том, что работу можно упростить. В идеале — если приведёте конкретные цифры.

Эффективность разработки новых функций

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

  • Работа с трудной для понимания кодовой базой снижает скорость разработки (и может увеличить количество и серьёзность новых ошибок).

  • Адаптация новых сотрудников от команды больше времени и усилий со стороны команды. Когда ещё новичок разберётся с вашей кодовой базой?

  • Чрезвычайно трудно внедрить новое решение в плохо спроектированную или устаревшую с точки зрения архитектуры систему. Так рождаются ужасные проекты рефакторинга.

  • Патчи и всевозможные костыли, которые вы добавляете в систему, существуют лишь вокруг неё. Это ещё больше усложняет систему и увеличивает технический долг. Самый настоящий порочный круг!

Способы расстановки приоритетов

Стоимость задержки

«Стоимость задержки» не является оптимальным методом приоритизации, но это очень хорошая метрика, когда речь идёт о рисках. Она сочетает в себе срочность и ценность, предлагая определить размазанные по определённому отрезку времени затраты, которые компания понесет, предоставляя эту конкретную функцию/проект/продукт позже, чем ожидает рынок или клиент.

Варианты того, как стоимость задержки будет вести себя с течением времени, можно увидеть на изображении ниже:

a482ed7fe17fd37e8edeb4b4cd939cac.png

Оценка ICE и RICE

Этот подход может помочь навести порядок в хаосе ожиданий, создавая понятную картину приоритетов, на основе которой можно сортировать задачи.

ICE расшифровывается как Impact, Confidence и Ease/Effort. R в RICE означает Reach.

Для каждого из этих факторов команда согласовывает набор баллов. Например, Критический = 3 Высокий = 2, Средний = 1, Низкий = 0,5, Минимальный = 0,25

Влияние (Impact). Какое влияние окажет решение этой проблемы на клиентов (помните, что клиенты могут быть и внутренними!) — или, говоря о риске, какое влияние окажет нерешённая проблема?

Уверенность (Confidence). Насколько вы уверены в своей оценке важности?

Легкость/усилие (Ease/Effort). Сколько усилий потребуется, чтобы решить проблему? Помните, что это относительная метрика, которую можно сравнить только с другими задачами из списка.

Охват (Reach) — на скольких людей это повлияет? 100% вашей клиентской базы? Только отдельных лиц?

Важно понимать, что эти оценки имеют значение только в каком-то конкретном случае. Когда у вас есть числа, расчёт прост:

RICE score = (Impact x Confidence) / Effort or Impact x Confidence x Ease

Ещё несколько советов

Предусматривайте ресурсы для работы с техдолгом

Я знаю, что многие команды выделяют какую-то часть рабочего времени на задачи из бэклога. Самая распространённая модель — это 70% для обычной работы, 20% для технического долга и 10% для обучения/экспериментов.

Проблема здесь кроется том, что крупные проблемы с техническим долгом никогда не решаются всего за 20% времени. Их переносят от спринта к спринту, в ходе переноса теряется контекст, и добиться нужного результата становится труднее. Ещё одна сложность заключается в невозможности соблюдения точных временных рамок при решении разных задач.

Договоритесь брать X задач в каждом спринте

Этот подход предполагает не обращать внимание на временные рамки, а просто брать и делать энное количество задач из бэклога в каждом спринте.

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

Относитесь к важным частям техдолга как к задачам

Иногда технический долг принимает форму длительных проектов, которые необходимо планировать и выполнять соответствующим образом. Так и относитесь к нему так же! Формулируйте четкое представление о цели, масштабе и поставленных целях (и измеряйте их!)

Делайте лучше

Есть хорошее правило: вы должны оставлять кодовые базы и системы в лучшем состоянии, чем вы их нашли. К средним задачам технического долга можно подходить именно таким образом. Вы можете резервировать ресурсы на частичное закрытие техдолга в ваших проектах.

Разумеется, для погашения технического долга необходимо работать не в одиночку, а командой.

Заключение

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

Источники

Что ещё интересного есть в блоге Cloud4Y

→ История Game Genie — чит-устройства, которое всколыхнуло мир

→ Как я случайно заблокировал 10 000 телефонов в Южной Америке

→ Странные продукты Apple

→ WD-40: средство, которое может почти всё

→ 30 лучших Python-проектов на GitHub на начало 2022 года

Подписывайтесь на наш Telegram-канал, чтобы не пропустить очередную статью. Пишем не чаще двух раз в неделю и только по делу.

© Habrahabr.ru