[Из песочницы] Гибкий рой: как спроектировать разделяемую работу для команд разработки ПО

Привет, Хабр! Представляю вашему вниманию перевод статьи «The agile swarm: How to design shareable work for software project teams» автора Stephen Frein.


Bees

Фото: Flickr

Успешные аджайл-команды склонны ограничивать незавершённую работу (НЗП, незавершённое производство). Предпочитают ли они Скрам, Канбан-метод, или какую-либо другую аджайл-методологию, эти команды особенно выделяют над всем остальным быструю разработку полезной функциональности.

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

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

Работа становится более разделяемой, когда она декомпозирована на архитектурные слои. Отдельные пользовательские истории должны быть представлены в виде тонких вертикальных срезов функциональности, проходящих через все слои приложения, от пользовательского или программного интерфейса, сквозь бизнес-логику опустившись до уровня БД. Нам нужны такие пользовательские истории, где мы можем пройти сквозь все архитектурные слои, потому что мы хотим дать нашим владельцам продуктов работающее ПО, а не изолированные технические компоненты, которые пока ещё не удовлетворяют потребности бизнеса и не могут быть оценены «нетехнарями».

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

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

К примеру, если наш каталог продукции разделён на две БД, с частью товаров в реляционной БД, частью — в документо-ориентированной, мы можем использовать шаблон проектирования DAO, определив единственный интерфейс доступа к данным товара и создавать отдельно имплементации для каждой БД.

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

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

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

Ещё один способ повысить разделяемость — отделить основную разработку от вспомогательной деятельности. Например, в то время, как один член команды работает над кодом для функциональности, другой может заниматься формированием тестовых данных, разрабатывать сквозные (end-to-end) сценарии с дополнительными системами, либо собирать недостающие требования.

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

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

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

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

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

Фундаментальным условием для такого движения является разделение. Командная работа «роением» взаимосвязана. Чтобы ваши «рои» двигались в одном направлении, научитесь делать вашу работу более разделяемой.

© Habrahabr.ru