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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Риски

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Оценка 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-канал, чтобы не пропустить очередную статью. Пишем не чаще двух раз в неделю и только по делу.

Комментарии (3)


  1. lxsmkv
    22.02.2022 13:52
    +2

    Был у нас один проект, где мне начальник сказал, мол, ты смотри, слово "(технический) долг" при заказчике не ляпни. Вот вопрос, если прям вот так все хреново, где клиент настолько "простой", что цепляется за каждое слово, как назвать технический долг, не называя его долгом.

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

    А как назвать технический долг в разработке не используя слова долг? Ну например, вы решили, что нужно все на Dependency Injection перевести. Это настолько далеко от понимания простых смертных, что нужны какие-то доступные объяснения. Может архитектор умеет такие вещи доносить до широких масс?


    1. vdasus
      23.02.2022 15:15
      +1

      Например: Надо создать способ, чтобы была возможность разрабатывать разные части разными командами и одна не ждала другую. Что можно уменьшить человеческий фактор (меньше вероятность что ошибка одного человека завалит все). Возможность легкого тестирования, когда изменение одной строки не потребует неделю работы Васи по всему проекту и тестам ну и так далее. Специфика вашей работы важна. Что важно бизнесу — на то и давить. Выявляете какие места проблемные у бизнеса (ресурсы, время, надежность, ...) и на понятном языке обьясняете руководству как DI поможет в уменьшении рисков, времени,… Я так делаю, часто работает.


  1. SergeyPeskov
    24.02.2022 14:28

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

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

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