Каждый продукт развивается своим собственным загадочным путем. Даже опытная команда не может предсказать каждый поворот в жизненном цикле продукта. Простые функции могут быть преобразованы в чудовищные многоусловные рабочие процессы. Некоторые быстро разработанные побочные сценарии могут стать наиболее используемыми. Даже популярность продукта может привести к неожиданным проблемам с производительностью. И совершенно нормально адаптировать программное обеспечение к потребностям рынка. Единственный способ иметь надежный и предсказуемый продукт — это зарезервировать некоторое время для исправления технического долга и обеспечения надлежащего процесса рефакторинга.
Лучше включить в эту статью некоторые определения терминов. Технический долг, или технический долг, — это накопленные компромиссы в кодовой базе, которые могут возникнуть во время быстрой разработки или других колебаний. Процесс рефакторинга больше касается улучшения продукта в целом. Он может включать действия, связанные с производительностью, лучшей структурой кода и простотой решения. Однако иногда эти два понятия могут быть очень близки. Например, несколько функций, полных технического долга, могут потребовать надлежащего рефакторинга всего модуля, чтобы исправить проблему раз и навсегда с помощью новых идей и повторной реализации.
И вот в чем фокус. В целом, у хороших разработчиков ПО есть много идей для улучшения продукта. «Ладно, мы могли бы подправить кое-что во время этой функции». «О, это не так важно, но было бы неплохо исправить это в этом побочном модуле». Тем не менее, крайне важно дать членам вашей команды возможность улучшить кодовую базу, так как это помогает создавать по-настоящему вовлеченные команды. Однако в этой статье я хотел бы раскрыть процесс рефакторинга с точки зрения менеджера. У приведенных выше примеров есть одна проблема — они могут быть непрозрачными для всей команды, кроме разработчиков. Хотя у QA и менеджеров есть свой план выпускать надлежащее и стабильное программное обеспечение по расписанию, некоторые скрытые улучшения могут создавать неожиданные повороты и нервные повторные тесты во время выпуска. Или даже новые ошибки в производстве, если на этапе регресса некоторые недокументированные изменения остаются незамеченными. Таким образом, улучшения кода необходимы, но они должны быть управляемыми.
Решение комплексное. Agile — наш лучший друг, потому что общие принципы и ритуалы методологий разработки Agile охватывают проблемные места. Вам нужно:
Под подготовкой я подразумеваю общение между членами команды перед итерацией, направленное на определение области итерации, уточнение требований, декомпозицию задач, оценку усилий и расстановку приоритетов для будущих рабочих элементов. Процесс планирования связан с результирующей областью итерации. Не каждая подготовленная задача может быть включена в итерацию.
Давайте подробнее рассмотрим каждую тему.
Самый простой способ для каждого разработчика создать бэклог технического долга — использовать теги «To do» в исходном коде. Позже вы можете выполнить поиск по кодовой базе, что-то улучшить и отправить запросы на извлечение для одобрения. Но этого недостаточно. Это не помогает членам команды обеспечить надлежащее планирование и быть уверенными в объеме релиза.
Лучшей альтернативой использованию «To Do» является установление процесса создания задач для будущих изменений. Если разработчик находит потенциально проблемное место или у него есть идея по улучшению кодовой базы, он должен создать рабочий элемент в системе тикетов (Jira, Azure DevOps или любой другой системе, которую использует команда). Было бы излишним требовать от инженеров предоставления подробного описания своей идеи для каждого члена команды, но объяснение должно быть достаточно ясным, чтобы руководитель группы понял ключевой момент и объем изменений. Это охватывает первый шаг — как мы можем создать список потенциальных задач и предоставить высокоуровневое описание будущих изменений.
Шаг второй — сделать его понятным для всех. Эту задачу может выполнить руководитель группы разработчиков, менеджер по выпуску или менеджер по продукту, в зависимости от их квалификации. Результат должен содержать следующие данные:
Если рабочий элемент содержит ответы на все эти вопросы, это помогает смягчить потенциальные проблемы в будущем. Однако наличие только бэклога недостаточно для управляемого рефакторинга. Вам необходимо планировать возможные изменения, и они должны быть постоянной частью вашего процесса. Конечно, вы столкнетесь с давлением бизнес-функций и требований рынка, где велик соблазн упустить технические задачи. Но без надлежащего обслуживания вы столкнетесь с еще большими проблемами в будущем.
Рекомендация по процессу технологического бэклога:
В каждой итерации команда должна резервировать время для технических улучшений.
Если есть какая-либо идея по улучшению, ее следует оформить в виде рабочего элемента с надлежащим описанием.
Рабочие элементы должны участвовать в процессе подготовки и обсуждаться всей командой до тех пор, пока не будут выявлены все преимущества и риски и не будут собраны оценки всех членов команды.
Рабочие элементы должны быть запланированы в Agile-итерациях в соответствии с их оценками.
Команда должна быть осведомлена о возможном объеме технического долга в итерации. Зарезервированное время может быть увеличено при необходимости, но никогда не должно быть меньше обычного количества. Это помогает мотивировать инженеров создавать новые задачи в бэклоге и расставлять их по приоритетам. Все знают, что их предложения могут быть реализованы, и бэклог когда-нибудь сократится, а не вырастет в огромный деморализующий список.
Иногда задачи технического долга могут быть выявлены во время обсуждения и оценки, в то время как команда столкнулась с неожиданными препятствиями, которые сделали реализацию менее надежной и гибкой. Например, вы можете понять, что есть похожие функции, и создание совершенно новой только ухудшит кодовую базу. Но эти функции не содержат бизнес-функциональности, требуемой в новых. И лучше создать унифицированный сервис, который связывает все похожие функции, чтобы упростить обслуживание в будущем. Тем не менее, это изменение может повлиять на старые функции и дестабилизировать их, и именно в этом заключается проблема. Возможно, есть способ разрабатывать новые функции дешево и закрывать глаза на недостатки. Или, может быть, прямо сейчас самая прекрасная возможность создать унифицированный сервис, пока есть только несколько похожих функций. Самое главное — установить процесс, который помогает членам команды принимать решения на основе выявленных фактов и должным образом подготовленных оценок. Крайне важно иметь систему, которая предотвращает ситуации, когда такие решения должны приниматься на этапе внедрения в фиксированном бэклоге.
Если ваши этапы итерации работают хорошо, раскрытие таких моментов будет происходить автоматически через надлежащий процесс подготовки и планирования. Есть несколько основных правил и шагов, которые могут защитить команду от неожиданных препятствий в большинстве случаев:
Проблемные элементы бэклога можно разложить на отдельные задачи и спланировать в соответствии с приоритетами. Решения о стратегии внедрения могут приниматься менеджером по релизам в соответствии с рисками и сроками. Но этот подход помогает документировать все решения. Даже если задача по техническому долгу была отложена, она все равно добавляется в бэклог. Позже эти задачи следует пересмотреть и запланировать. Этот процесс исправляет сценарии, когда некоторые хорошие и нужные идеи забываются во время лихорадочной итерации.
Тем не менее, даже при хорошо поддерживаемом техническом долге и рабочем процессе подготовки и планирования, можно столкнуться с неожиданными и трудоемкими препятствиями в процессе разработки. Программные продукты могут быть сложными, особенно старые или содержащие богатую функциональность.
Использование Agile-практик помогает собирать информацию на ранних этапах и принимать правильные решения. Одно из самых простых решений — ежедневные встречи.
Если инженер сталкивается с какой-то проблемой, ее следует поднять во время встречи и обсудить позже. Каждое препятствие уникально и может потребовать разного количества времени. Неважно, будет ли изменение реализовано в текущей итерации вместо функции «Неплохо бы иметь» или потребует полного пересмотра объема итерации. Проблема должна быть создана как типичная задача технического долга в системе отслеживания, разложена и описана как любая другая похожая задача в предыдущих статьях. Последовательность — это ключ, и команда должна знать, как справляться с такими ситуациями.
Все эти методы могут показаться дополнительным способом занять время всей команды бесполезной бюрократией. И это могло бы быть так, если бы только отсутствие строгих и четких правил не создавало трудности для всех. Нормально не следовать этим рекомендациям в краткосрочных проектах или на этапе минимально ценного продукта (MVP). Однако работа в производстве с качественными обязанностями и большими продуктами требует четко определенной внутренней системы процессов. Давайте рассмотрим наиболее распространенные возражения.
И это правда. Описывать свои задачи на естественном языке иногда может быть сложнее, чем исправлять код. Но вот несколько решений:
Может быть. Но это зависит от объяснения. Приоритетом является описание того, что может пойти не так и какая функциональность может быть дестабилизирована. Однако полезно писать о влиянии изменений, поскольку это помогает выявить дополнительные возможности и сценарии. Кроме того, даже самые глубоко технические идеи можно описать простыми предложениями с использованием естественного языка. Если это невозможно, то может быть что-то не так с самой идеей, и это может быть потенциальным риском, все предложение следует пересмотреть.
Просто напишите что-то вроде:
«Метод «XXX» потребляет слишком много оперативной памяти при каждом вызове. Создание дополнительного кэша для этого метода помогает снизить потребление оперативной памяти и ускорить все API. Метод использует данные, которые редко меняются, достаточно сбросить кэш при перезапуске. Изменения безопасны, но могут потенциально повлиять на следующие функции: XXX, XXX, XXX…».
В некоторых случаях этого будет достаточно. В других случаях это предложение может спровоцировать обсуждение, поскольку инженер может забыть о какой-то старой, но все еще используемой функциональности, где этот кэш мог бы вызывать проблемы. В процессе обработки идея будет пересмотрена, и команда найдет компромисс.
Стабильность и надежность лучше, чем несколько процентных улучшений времени выполнения некоторых функций. Никто не будет разочарован, если упустите потенциальный прирост производительности, но репутацию продукта легко запятнать.
Идея заключается в том, чтобы оптимизировать процессы и помочь оценить риски. Инженеры должны иметь возможность поддерживать кодовую базу и вносить некоторые улучшения. Для вещей, которые незначительны и не дестабилизируют весь продукт, можно создавать агрегированные рабочие элементы, которые могут быть выполнены во время итерации. Эти задачи по-прежнему необходимо рассматривать как запросы на извлечение, но не обязательно официально объявлять о них команде.
Постоянное улучшение продукта имеет решающее значение для бизнеса и помогает сохранить общее качество. Если вы держите технический долг и новые идеи на полке, вы застрянете с устаревшим продуктом и вскоре будете бороться с поиском опытных инженеров для его обслуживания.
С другой стороны, эти задачи конкурируют с бизнес-функциями и другими идеями, которые могут вывести бизнес на новые горизонты. Эти рекомендации по бэклогу технических задач могут помочь выявить и оценить важность этих задач не только для членов команды, но и для заинтересованных сторон. Они помогают представить эти идеи на естественном языке и сохранить и защитить время для внедрения. Это обременяет инженеров дополнительными действиями, но в конечном итоге помогает всей команде поставлять высококачественные и надежные продукты. И ответственность менеджера заключается в выборе правильного инструмента или политики для поддержания этого процесса.