Agile: оценка и планирование проектов

Кон Майк

Часть IV

Составление календарных графиков

 

 

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

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

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

 

Глава 13

Основные аспекты планирования релиза

 

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

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

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

В-третьих, план релиза служит ориентиром, по отношению к которому команда может оценивать прогресс. Без концепции релиза команды бесконечно переходят от одной итерации к другой. План релиза создает контекст, который позволяет объединить итерации в отвечающее запросам потребителей целое. Это фундаментальная цель любого итеративного процесса, а не только agile-процесса. Турист, который хочет добраться до вершины горы, может ориентироваться на самый высокий видимый пик. Однако после достижения этой вершины он узнает, что пик был ложным. Более высокую вершину не было видно за тем пиком, который он покорил. Турист нацеливается на эту, более высокую вершину, но лишь обнаруживает, что и она является ложной, поскольку теперь ему видна еще более высокая вершина. Такой непрямой путь покорения вершин в равной мере применим и к итеративным проектам. К счастью, проблемы, которые он создает, устраняются в результате составления плана релиза, показывающего текущие ожидания команды в отношении того, куда она хочет в конечном итоге добраться.

 

План релиза

 

Частью планирования релиза является определение, какой объем работы можно выполнить и к какой дате. В одних случаях мы начинаем с даты и смотрим, какой объем работы можно завершить. В других случаях мы начинаем с набора пользовательских историй и смотрим, сколько времени потребуется для их реализации. В обоих случаях, как только команда получает первоначальный ответ, он оценивается относительно целей организации в проекте: принесет ли разработанный продукт желаемое количество денег? Поможет ли он сэкономить достаточно денег? Позволит ли продукт получить целевую долю рынка? Если нет, то, может быть, более продолжительный или короткий проект позволит достичь приемлемой комбинации целей.

В первом приближении определение того, какой объем работы потребуется для релиза и какие пользовательские истории войдут в него, выглядит очень простым — умножение планового количества итераций на ожидаемую или известную скорость команды дает нам общий объем работы, которую можно выполнить. Затем подбирается такое количество пользовательских историй, которое соответствует общему объему работы. Предположим, что мы хотим отгрузить новый продукт через шесть месяцев. Мы планируем работать двухнедельными итерациями, поэтому в нашем проекте будет 13 итераций. Мы ожидаем, что скорость команды составит 20 пунктов или идеальных дней на итерацию. Тогда размер всего проекта будет равен 13 × 20 = 260 пунктов или идеальных дней. Теперь владелец продукта и команда могут обсудить все истории и определить их приоритет, с тем чтобы создать наибольшую стоимость и при этом не выйти за пределы 260. План релиза обычно представляет собой перечень пользовательских историй, которые будут реализованы в течение проекта.

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

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

Основные этапы планирования релиза показаны на рис. 13.1. Каждый из этих этапов описывается в следующих разделах.

 

Определение условий удовлетворенности

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

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

 

Оценка пользовательских историй

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

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

 

Выбор длины итерации

Большинство agile-команд работают с итерациями продолжительностью от двух до четырех недель. Итерации могут быть и чуть длиннее, а некоторые команды экспериментируют с более короткими сроками. При планировании релиза необходимо выбрать подходящую длину итерации. Рекомендации по выбору представлены в главе 15 «Выбор длины итерации».

 

Оценка скорости

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

 

Приоритизация пользовательских историй

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

 

Выбор историй и даты релиза

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

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

Если проект ориентирован на сроки, мы можем определить количество итераций, глядя на календарь. Умножение количества итераций на ожидаемую скорость покажет нам, сколько пунктов или идеальных дней уложатся в релиз. Это количество пунктов или идеальных дней можно соотнести с приоритизированным перечнем пользовательских историй и понять, какую функциональность возможно реализовать к желаемому сроку.

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

У каждого подхода есть свои преимущества и недостатки. Понятно, что распределение конкретных функций по конкретным итерациям занимает больше времени. Вместе с тем прорабатываемые при этом детали могут быть полезными при координировании работы нескольких команд. Отказ от распределения работы по конкретным итерациям обеспечивает меньшую детализацию, но отнимает намного меньше времени. Помимо прочего, в случае предварительного распределения работы по конкретным итерациям мы делаем это на основе меньшего объема знаний, чем при распределении перед началом каждой итерации. План, несомненно, будет изменяться по мере того, как мы узнаем больше в ходе выполнения проекта. Как следствие, затраты времени и сил на распределение работы по конкретным итерациям необходимо взвешивать относительно этого аспекта. Так или иначе, в некоторых проектах данный подход имеет смысл. Разумным компромиссом, на мой взгляд, является распределение конкретных работ по первым двум-трем итерациям и представление оставшейся части плана релиза в виде единого блока. Практически всегда стоит определять конкретные работы для первой итерации, особенно если она начинается сразу же.

Из-за множества мнений и вопросов типа «что… если…» во время типичной сессии по планированию релиза неплохо было бы иметь удобный способ управления входными и выходными параметрами релиза и итерациями. Лучше всего, при условии что каждый знает свою задачу, работать с карточками размером 6×12 см или стикерами с пользовательскими историями или функциями. В отличие от программных средств карточки осязаемы, и их легко может прочитать каждый.

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

 

Обновление плана релиза

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

 

Пример

 

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

• Как тренер я могу определять расписание тренировок.

• Как тренер я могу определять по своему желанию поля для отслеживания по каждому пловцу.

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

• Как пловец я могу корректировать свою гендерно-возрастную информацию.

• Как тренер я могу рассылать электронные письма всем пловцам команды.

• Как системный администратор я могу конфигурировать права доступа и пользовательские группы.

• Как тренер я могу приобретать программу SwimStats и использовать ее вместе со своей командой.

• Как пловец я могу сравнивать свои результаты с национальными рекордами.

• Как тренер я могу вводить имена и гендерно-возрастную информацию по всем пловцам моей команды.

• Как пловец я могу видеть мое лучшее время в каждых соревнованиях.

• Как пользователь я должен зарегистрироваться в системе и могу видеть только данные, к которым мне разрешен доступ.

• Как пловец я могу видеть все мои результаты в конкретных соревнованиях.

 

Определение условий удовлетворенности

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

 

Оценка

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

 

Выбор длины итерации

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

 

Оценка скорости

В этом проекте будут заняты два программиста и один тестировщик. Используя приемы, описанные в главе 16 «Оценка скорости», они закладывают скорость восемь пунктов на итерацию.

 

Приоритизация пользовательских историй

Владелец продукта, опираясь на выполненное исследование рынка, расставляет приоритеты историй. Перечень приоритизированных историй вместе с оценкой каждой из них приведен в табл. 13.1.

 

Выбор пользовательских историй

Поскольку это проект, ориентированный на сроки, мы знаем, сколько итераций в нем может быть. Владелец продукта хочет получить релиз через три месяца — это шесть двухнедельных итераций плюс дополнительная неделя для непредвиденных случаев. При предполагаемой скорости восемь пунктов на итерацию релиз будет включать 6 × 8 = 48 пунктов. Теперь владелец продукта может выбрать для включения в релиз работу объемом до 48 пунктов из табл. 13.1.

Пользовательские истории в табл. 13.1 рассортированы владельцем продукта по убыванию их ценности для первого релиза SwimStats. Владелец продукта может выбрать до 48 пунктов. Первоначально он выбирает первые восемь историй, включая «Как пловец я могу сравнивать свои результаты с национальными рекордами». Это составляет в сумме 46 пунктов, что довольно близко к согласованным предельным 48 пунктам.

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

Так или иначе, команда SwimStats не решается на увеличение объема до 49 пунктов. Если добавить трехпунктовую историю, то из релиза необходимо исключить как минимум один пункт. Владелец продукта принимает решение удалить историю «Как пловец я могу сравнивать свои результаты с национальными рекордами» на восемь пунктов. Это уменьшает релиз до 41 пункта. Владелец продукта мог бы добавить трехпунктовую историю «Как тренер я могу рассылать электронные письма всем пловцам команды», но он предпочитает воздержаться от этого. Если команда выполнит хотя бы один пункт раньше календарного графика, то он предпочтет вернуть назад исключенную восьмипунктовую историю. В результате окончательный план релиза принимает форму, приведенную в табл. 13.2.

 

Резюме

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

План релиза не должен в точности описывать, чтó будет разрабатываться в течение каждой итерации. В реальности такой уровень детализации требуется редко. Для большинства проектов вполне достаточно идентифицировать истории, которые пойдут в работу в первой паре итераций, а остальные истории должны распределяться по конкретным итерациям позднее.

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

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

 

Вопросы для обсуждения

1. Каким является ваш текущий проект, ориентированным на сроки или на функции? Почему он именно такой?

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

 

Глава 14

Планирование итерации

 

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

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

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

Альтернатива электронной таблице представлена на рис. 14.1, который иллюстрирует использование карточек для планирования итерации. Карточки можно расположить, как на этом рисунке, на столе или на полу, а также приклеить их или прикрепить кнопками к стене. Лично я предпочитаю планировать итерации с использованием карточек. Члены команды могут покидать совещание по планированию и сразу вводить карточки в компьютерную систему, если им хочется, но на самом совещании намного удобнее пользоваться карточками.

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

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

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

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

 

Задачи, не распределенные во время планирования итерации

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

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

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

 

Чем различаются планирование итерации и планирование релиза

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

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

Эти основные различия между планом релиза и планом итерации представлены в обобщенном виде в табл. 14.2.

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

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

 

Планирование итерации на основе скорости

 

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

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

 

Корректировка приоритетов

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

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

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

Анализ итерации обычно занимает от 30 до 60 минут. В случаях крупных продуктов при участии нескольких команд бывает, что владелец продукта и другие ключевые заинтересованные лица, необходимые для обсуждения приоритетов, тратят на анализ итерации полдня. Добавьте к этому четыре часа на планирование итерации, и у вас может не остаться времени для обсуждения приоритетов в тот же день.

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

 

Определение целевой скорости

Следующий этап планирования итерации на основе скорости — определение целевой скорости команды. По умолчанию большинство команд принимают свою скорость в следующей итерации равной скорости в ближайшей прошлой итерации. Бек и Фаулер (Beck and Fowler, 2000) называют это вчерашней погодой, поскольку самый лучший прогноз сегодняшней погоды тот, который похож на вчерашнюю погоду. Есть и такие команды, которые предпочитают использовать скользящие средние, скажем, за последние три итерации.

Если команда не работала вместе прежде или не знакома с agile-процессом, то ей придется спрогнозировать скорость. Методы прогнозирования скорости описаны в главе 16 «Оценка скорости».

 

Идентификация цели итерации

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

• Добиться прогресса по отчетам.

• Завершить реализацию всех отчетов по результатам в соревновании.

• Обеспечить работоспособность функции безопасности.

Цель итерации — это единое заявление о том, что должно быть реализовано в течение данной итерации. Она не должна быть очень конкретной. Например, «Добиться прогресса по отчетам» — хорошая цель итерации. Ее не нужно делать более конкретной, например «Завершить 15 отчетов» или «Выполнить отчеты по результатам соревнования». Если «Добиться прогресса по отчетам» наглядно описывает, над чем придется работать в предстоящей итерации, то это хорошее заявление об этой цели.

 

Выбор пользовательских историй

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

• Как пловец я могу корректировать свою гендерно-возрастную информацию.

• Как тренер я могу вводить гендерно-возрастную информацию по всем пловцам моей команды.

• Как тренер я могу импортировать файл со всеми гендерно-возрастными данными.

• Как тренер я могу экспортировать файл со всеми гендерно-возрастными данными.

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

 

Разбивка пользовательских историй на задачи

 

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

• Определение правил, которые влияют на то, кого можно поставить на какой заплыв.

• Написание тестовых сценариев, показывающих, как это должно работать.

• Разработка пользовательского интерфейса.

• Получение обратной связи по пользовательскому интерфейсу от тренеров.

• Кодирование пользовательского интерфейса.

• Кодирование среднего яруса.

• Добавление новых таблиц в базу данных.

• Автоматизация приемочных тестов.

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

 

Включайте только ту работу, которая создает стоимость для соответствующего проекта

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

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

 

Будьте конкретны, пусть это станет привычкой

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

 

Учет совещаний (которых будет множество)

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

 

Программные ошибки

Agile-команды стремятся устранять все ошибки в той итерации, в которой они обнаруживаются. Это становится возможным с приобретением опыта работы в режиме коротких итераций, в частности в результате применения автоматического тестирования. Когда программист дает оценку задачи по кодированию чего-либо, он включает в нее время на устранение ошибок, выявленных в процессе реализации, или выделяет этот процесс и оценивает его как отдельную задачу («Устранение ошибок»). Я предпочитаю представлять это в виде отдельной задачи, но не считаю ее завершенной до тех пор, пока не будут выполнены все тесты.

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

 

Подход к работе с взаимозависимостями

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

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

В качестве примера допустим, что естественный порядок для веб-сайта SwimStats предполагает реализацию функций, которые позволяют пользователю добавлять новых пловцов в систему, а затем реализацию функций, позволяющих пользователю просматривать лучшие результаты каждого пловца в соревнованиях. Было бы странно выискивать лучшие результаты до получения окон для добавления пловцов в систему. Это, однако, может быть сделано, если владелец продукта и команда захотят разрабатывать функции в таком порядке. Для этого, конечно, необходимо в достаточной мере проработать базу данных так, чтобы она могла накапливать информацию по пловцам и их результатам. Команде также придется ввести в базу данных информацию как минимум об одном пловце и его результатах. Поскольку это часть функции, которую она не хочет разрабатывать в первую очередь, придется добавлять пловца (и его результаты) в базу данных напрямую, а не через пользовательский интерфейс и разработанную программу.

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

Означает ли это, что работа не в естественном порядке увеличивает срок выполнения проекта? Ответов может быть два: «не обязательно» и «это не имеет значения».

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

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

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

 

Работа, которую трудно разбить

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

• Определение того, что затрагивается, — два часа.

• Внесение изменений — 10 часов.

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

 

Оценка задач

 

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

Хотя я согласен с общепризнанным мнением, что лучше всего оценивает тот, кто выполняет работу (Lederer and Prasad, 1992), на мой взгляд, оценка в agile-проекте должна быть коллективным занятием. Для этого есть четыре причины.

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

Во-вторых, даже если мы предполагаем, кто именно будет выполнять задачу, и даже если этот исполнитель знает больше всех о данной задаче, это не означает, что другим нечего добавить. Допустим, во время совещания по планированию итерации Джеймс говорит: «Мне потребуется примерно два часа, чтобы запрограммировать функцию, — это тривиально!» Однако вы помните, что в прошлом месяце у Джеймса была похожая задача и он дал такой же комментарий, но на выполнение той задачи ушло почти 16 часов. В этот раз, когда Джеймс скажет, что такая задача требует всего лишь два часа, вы можете добавить: «Но, Джеймс, в прошлый раз, когда ты работал над похожей задачей и тоже оценивал ее в два часа, на нее в действительности ушло 16 часов». Скорее всего, Джеймс назовет разумную причину, по которой в этот раз все будет иначе, однако он может согласиться с тем, что с такими задачами связаны определенные трудности, которые он систематически упускает из виду.

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

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

 

Обсуждение дизайна — это нормально

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

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

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

 

Подходящий размер для задачи

Создаваемые вами задачи должны иметь примерно такой размер, чтобы каждый разработчик мог завершать в среднем одну из них за день. Подобный размер очень удобен для равномерного выполнения работы в течение всего agile-процесса разработки. Более крупные задачи нередко задействуют одного-двух разработчиков, а остальные члены команды вынуждены ждать, пока те завершат свою работу. Кроме того, если команда проводит короткие ежедневные совещания (Schwaber and Beedle, 2002; Rising, 2002), то однодневные задачи позволяют каждому разработчику отчитываться о завершении как минимум одной задачи практически каждый день.

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

 

Планирование итерации на основе обязательств

 

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

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

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

 

Запрос на принятие обязательств

 

В своем исследовании факторов успеха команд Ларсон и Лафасто (Larson and LaFasto, 1989) установили, что единое обязательство, принятое всеми членами команды, является одним из ключевых факторов успеха. Во время совещания по планированию итерации я спрашиваю команду: «Можете ли вы принять обязательство реализовать функции, которые мы обсудили?» Обратите внимание на то, что я не спрашиваю, смогут ли они принять обязательство реализовать задачи, которые мы идентифицировали. Это совершенно другой вопрос и значительно более слабое обязательство, поскольку оно относится к выполнению набора задач, а не к постановке новой функциональности.

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

Я спрашиваю команду, сможет ли она принять обязательство по реализации после разбивки каждой пользовательской истории на задачи и оценки этих задач. Применительно к первой пользовательской истории такой вопрос может показаться глупым. В команде, планирующей двухнедельную итерацию, может быть семь человек. Может так случиться, что они идентифицировали работу пока всего лишь на 34 часа, а я спрашиваю, смогут ли они принять обязательство по ее выполнению. Их ответ (либо в словесной форме, либо в виде смущения на лицах), без сомнения, будет следующим: «Конечно, мы можем принять обязательство выполнить это. Нас семь, и у нас целых две недели, а здесь работы всего на 34 часа». Вместе с тем чем дальше продвигается обсуждение и чем больше пользовательских историй включаются в итерацию, тем более тщательного обдумывания требует мой вопрос о возможности принятия обязательства. В конечном итоге наступает предел, за которым команда уже не может увеличивать объем обязательств. В таком случае она может исключить историю или заменить ее на более мелкую перед завершением обсуждения.

 

Суммирование оценок

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

Допустим, команда работает с использованием двухнедельных итераций. В каждой итерации ей доступно 560 часов (7 человек × 10 дней × 8 часов в день). Мы знаем, что определенное время тратится на деятельность, не отраженную в карточках с задачами, — ответы на электронные письма, участие в совещаниях и т. д. Также нам известно, что оценки неточны; в конце концов, это оценки, а не гарантированные величины. По этим причинам нельзя ожидать, что эта команда возьмется за выполнение задач объемом 560 часов. На практике большинство команд успешно справляются с работой, когда ее плановый объем (сумма оценок на карточках с задачами) составляет от четырех до шести часов в день. Для нашей команды из семи человек, работающей двухнедельными итерациями, это означает плановый объем работы от 280 до 420 часов. В какой точке этого диапазона команда остановится, зависит от того, насколько хорошо она идентифицирует задачи для данной истории, насколько точно оценивает эти задачи, а также от объема сторонних обязательств членов команды и размера общекорпоративных непроизводительных издержек. После пары итераций большинство команд начинают примерно чувствовать, какой объем работы в часах они должны планировать на итерацию.

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

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

Индивидуальные обязательства

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

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

 

Сопровождение других продуктов и обязательство

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

Я представляю себе итерацию как пустой стакан. Первое, что наливают в стакан, — это неизменные обязательства команды, такие как поддержка и обслуживание других продуктов. Оставшееся в стакане пространство доступно для принятия обязательств по выполнению работы во время итерации. Графически этот образ представлен на рис. 14.4. Понятно, что у команды, чей стакан на 10 % заполнен работой, связанной с поддержкой, будет больше времени на выполнение другой работы, чем у команды, чей стакан изначально наполнен на 90 %.

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

 

Мои рекомендации

Эффективны оба подхода — и планирование итерации на основе скорости, и планирование итерации на основе обязательств. Я, однако, предпочитаю подход на основе обязательств. Хотя скорость играет критическую роль в планировании релиза, я не считаю, что она должна играть такую же роль при планировании итерации. Для такого заявления есть две причины.

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

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

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

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

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

 

Соотнесение оценок задач с пунктами

Меня нередко просят объяснить взаимосвязь между оценками задач, используемыми при планировании итерации, и пунктами или идеальными днями, используемыми для более долгосрочного планирования релиза. По моим наблюдениям, команды сбиваются с пути, когда начинают верить в то, что между пунктами и точным числом часов существует сильная взаимосвязь. Так, сравнительно недавно я работал с одной командой, которая отслеживала фактическое количество продуктивных часов на итерацию и скорость на итерацию. На основе полученных данных она рассчитала, что каждый пункт соответствует примерно 12 часам работы. Команда ошибочно решила, что один пункт всегда равен 12 часам работы. Вместе с тем в реальности мы имеем нечто близкое к тому, что показано на рис. 14.5.

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

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

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

Дни недели

Когда я только стал руководить agile-проектами, мои команды обычно начинали выполнение итераций в понедельник и завершали их в пятницу. Мы делали это независимо от того, какие итерации использовались — двух-, трех- или четырехнедельные. Понедельник казался самым естественным днем для начала итерации, а пятница — для ее завершения. Мои представления, однако, изменились после того, как я взялся за обучение команды, разрабатывавшей веб-сайт, который активно использовался в будни и практически не посещался в выходные.

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

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

 

Резюме

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

Существует два основных подхода к планированию итерации: планирование на основе скорости и планирование на основе обязательств. У этих подходов много общих этапов, а их применение нередко приводит к одному и тому же результату, т. е. дает один и тот же план итерации.

 

Вопросы для обсуждения

1. Какой подход к планированию итерации вы предпочитаете: на основе скорости или на основе обязательств? Почему?

2. Как вы относитесь к идее отказа от распределения конкретных задач между членами команды во время планирования итерации?

 

Глава 15

Выбор длины итерации

 

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

 

Факторы, влияющие на выбор длины итерации

 

При выборе длины итерации вы должны руководствоваться следующими факторами:

• Длина релиза, над которым ведется работа.

• Уровень неопределенности.

• Простота получения обратной связи.

• Продолжительность сохранения неизменности приоритетов.

• Готовность продолжать работу без получения внешней обратной связи.

• Издержки итерационного подхода.

• Быстрота появления ощущения цейтнота.

Какой-либо предопределенной относительной важности этих факторов не существует. Важность каждого из них полностью зависит от контекста проекта.

 

Общая длина релиза

Короткие проекты выигрывают от использования коротких итераций. От длины итераций проекта зависят следующие аспекты:

• Частота демонстрации программного продукта (в потенциально готовом виде) пользователям и клиентам. Конечно, программу можно показать публике и в середине итерации, но она обычно приобретает потенциально готовую форму только к концу итерации.

• Частота измерения прогресса. Представление о скорости прогресса команды можно получить и в процессе итерации, однако только к ее концу можно достоверно измерить объем выполненной работы.

• Частота уточнения направления работы владельцем продукта и командой, поскольку приоритеты и планы корректируются между итерациями.

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

Мой опыт говорит о том, что в течение проекта такая возможность должна появляться не менее четырех-пяти раз. Таким образом, если общая продолжительность проекта составляет четыре месяца и более, то вполне можно рассмотреть целесообразность использования месячных или четырехнедельных итераций. Если же общая длина релиза меньше, то в проекте необходимо использовать пропорционально более короткие итерации.

 

Уровень неопределенности

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

 

Простота получения обратной связи

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

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

 

Продолжительность сохранения неизменности приоритетов

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

Ключевым соображением является время, необходимое для превращения хорошей новой идеи в работающую программу. Возьмем для примера команду, использующую четырехнедельные итерации. Если предположить, что новые идеи с одинаковой вероятностью могут возникнуть в любой момент в процессе осуществления итерации, то в среднем появление новой идеи должно приходиться на середину итерации. Эта новая идея будет приоритизирована в следующей итерации, которая начнется через две недели. Еще четыре недели (полная итерация) потребуется на то, чтобы новая идея превратилась в потенциально готовую работающую программу. Этот процесс представлен на рис. 15.1. Ключевой момент, который необходимо вынести из этого примера, заключается в том, что время с момента появления новой идеи до создания работающей программы составляет в среднем полторы длины итерации, используемой командой.

Как говорилось в главе 14 «Планирование итерации», команда, на которой лежат обязанности по обслуживанию или поддержке, помимо новой разработки, всегда резервирует определенное время на работы, связанные с обслуживанием и поддержкой. На рис. 15.1 показана реальная ситуация, в которой некто предлагает команде идею, не укладывающуюся в ее резерв на обслуживание и поддержку.

 

Готовность продолжать работу без получения внешней обратной связи

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

 

Издержки итерационного подхода

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

 

Быстрота появления ощущения цейтнота

Мой коллега Нильс Малото (Malotaux, 2004) подчеркивает, что «пока дата окончания проекта где-то далеко в будущем, на нас ничто не давит и мы работаем неторопливо». Когда же дата завершения появляется на горизонте, мы начинаем работать интенсивнее. Дата завершения даже четырехнедельных итераций не так уж далека. Однако до нее достаточно много времени, чтобы многие команды ощущали заметно меньшее напряжение в течение первой недели, чем в течение четвертой и последней недели итерации.

Решением в этом случае является выбор такой длины итерации, которая выравнивает давление, ощущаемое командой. Идея не в том, чтобы усилить давление на команду («Вы должны закончить работу сегодня!»). Речь идет о более равномерном распределении нормального стресса по итерации подходящей длины.

Не меняйте выбранной длины, если хотите добиться стабильного ритма

Какую бы длину итерации вы ни выбрали, лучше придерживаться ее и не менять то и дело. При использовании постоянной длины итерации у команд вырабатывается естественный ритм. Когда я начал заниматься agile-разработкой и применять один из ранних вариантов методологии Scrum (Takeuchi and Nonaka, 1986; DeGrace and Stahl, 1990), мои команды обычно выбирали длину каждой итерации в зависимости от объема работ, который предполагалось выполнить. За двухнедельной итерацией могла следовать шестинедельная итерация, а за ней — четырехнедельная и т. д. Опыт, полученный в результате выполнения множества проектов, показал, что команды намного лучше подгоняют объем работ к длине итерации, а не длину итерации к объему работ.

Стабильный ритм выполнения итерации — это своего рода сердцебиение проекта. Коллега Саймон Бейкер, agile-тренер в think-box ltd., говорит об этом так: «Как сердцебиение, стабильность которого необходима для жизнедеятельности организма, фиксированная длина итерации является константой, помогающей задать ритм разработки (и поставки). Ритм в моей практике — значимый фактор, который позволяет поддерживать устойчивый темп» (Baker, 2004).

 

Принятие решения

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

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

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

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

6 × 2 + 1

Непрерывная работа с использованием двухнедельных итераций может сильно напрягать команду в результате постоянной необходимости выдавать готовый продукт в условиях, когда срок сдачи работы не выходит за пределы следующей недели. Мой любимый прием снижения этого напряжения — работа макроциклами из шести двухнедельных итераций, за которыми следует однонедельная итерация. Я обозначаю этот цикл как «6 × 2 + 1». Во время двухнедельных итераций команда работает над элементами, приоритизированными владельцем продукта. Для однонедельной итерации команда подбирает работу самостоятельно. Это не означает, что она использует это время для игр или проводит неделю на пляже. Члены команды фокусируются в течение этой недели на той работе, которую они считают приоритетной для проекта. Программисты могут заняться реорганизацией кода, выполнять которую в середине другой итерации, на их взгляд, рискованно, или поэкспериментировать с новыми технологиями. Тестировщик может заняться автоматизацией существующих ручных тестов. Аналитик может заняться исследованием следующей крупной функции, которой, по его мнению, было уделено недостаточно внимания.

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

 

Два примера

 

Чтобы понять, как применять эти факторы, рассмотрим две команды: команду проекта Napa и команду проекта Goodman. Эти команды совершенно реальны, изменены лишь некоторые детали.

 

Проект Napa

Команда проекта Napa в составе семи человек разрабатывала клиент-серверное приложение для настольных компьютеров. Приложением должны были пользоваться 600 работников компании. Приложение не предполагалось продавать или использовать за пределами компании. Пользователи располагались в трех городах, в одном из которых находилась команда разработчиков в полном составе. Идея продукта зародилась в процессе обновления существующей системы, обслуживание которой стало слишком дорогим. Как следствие изменений в ключевом бизнесе компании, в проект запланировали включить большое количество новых функций. По оценкам, проект должен был занять 13 месяцев, однако быстрый рост компании сделал необходимым ранний выпуск релиза, пусть даже с ограниченной функциональностью.

Для проекта Napa команда выбрала четырехнедельные итерации. Мы знали, что выполнение проекта займет не менее шести месяцев, поэтому даже четырехнедельные итерации давали массу возможностей привести программу в состояние потенциальной готовности к выпуску релиза, который можно передать реальным пользователям. Проект характеризовался довольно большим, но не чрезмерным набором требований и неопределенностью технологии. Все разработчики имели большой опыт в использовании текущих технологий (C++ и Oracle). Хотя новое приложение должно было иметь функции, значительно выходящие за пределы возможностей существующего, старое приложение приняли за базовую модель того, что необходимо.

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

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

 

Проект Goodman

Команда проекта Goodman работала над первой версией коммерческого приложения для корпораций. В течение первых трех лет компания предполагала продать не более 5000 лицензий на программу. Вместе с тем продукт был дорогим, со средней ценой $50 000 на пользователя. Разработчиков, общая численность которых составляла 18 человек, разбили на две скоординированно работающие команды. Ожидалось, что выполнение проекта Goodman займет один год, однако предварительный релиз планировали передать небольшому числу клиентов через шесть месяцев.

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

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

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

Избегайте конца квартала

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

Мне довелось участвовать в одном проекте, в котором выпуск нового релиза был запланирован на пятницу 31 марта 2000 г. Этот релиз был ключевой целью девятимесячного периода работы компании (такой срок является предельным для отдельно взятого релиза). За две недели до срока выпуска релиза наш владелец продукта отправился в отпуск со своими детьми школьного возраста. Находясь в Диснейленде, он доблестно пытался решить по телефону несколько очень важных для нас вопросов. Однако его отсутствие пришлось на критический момент, и нам так и не удалось завершить определенную работу в последней итерации перед выпуском крупного релиза.

После возвращения владельца продукта мы смогли решить все оставшиеся вопросы в течение более короткой однонедельной итерации. Это отодвинуло дату выпуска релиза с 31 марта на 7 апреля. Хотя задержка на одну неделю не кажется критической для проекта со сроком выполнения девять месяцев, на практике она привела к переносу поставки продукта с одного квартала на другой, а это имело огромное значение для публичной компании. Из-за того, что плановая поставка нескольких сотен копий, намеченная на 31 марта, не состоялась, выручку от продаж и обновлений уже нельзя было признать в первом квартале. С таким же успехом эту поставку можно было осуществить 30 июня, а не 7 апреля.

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

 

Резюме

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

• длина релиза, над которым ведется работа;

• уровень неопределенности;

• простота получения обратной связи;

• продолжительность сохранения неизменности приоритетов;

• готовность продолжать работу без получения внешней обратной связи;

• издержки итерационного подхода;

• быстрота появления ощущения цейтнота.

 

Вопросы для обсуждения

1. Какая длина итерации больше всего подходит для вашего текущего проекта?

2. Что изменится в вашем проекте при использовании однонедельных итераций? Что изменится в случае использования двухмесячных итераций?

 

Глава 16

Оценка скорости

 

Одной из проблем при планировании релиза является оценка скорости команды. Существует три подхода к ее решению:

• использовать исторические значения;

• выполнить одну итерацию;

• воспользоваться прогнозом.

Бывает, что применимы все три подхода. Так или иначе, несмотря на выбранный подход, при оценке скорости результат следует представлять в виде диапазона. Допустим, вы оценили скорость команды в определенном проекте как 20 идеальных дней на итерацию. Шансы на то, что вы дали правильную оценку, очень ограничены. Скорость может составлять 21, 19 и даже 20,0001. Поэтому не говорите, что скорость равна 20, а давайте диапазон, например скажите, что ваша скорость находится в интервале между 15 и 24.

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

 

Использование исторических значений

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

• Осталась ли прежней технология?

• Осталась ли прежней область деятельности?

• Осталась ли прежней команда?

• Остался ли прежним владелец продукта?

• Остались ли прежними инструменты?

• Осталась ли прежней рабочая среда?

• Были ли эти оценки сделаны теми же людьми?

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

Если же ответ на любой из перечисленных выше вопросов отрицателен, то следует дважды подумать, прежде чем использовать исторические скорости. Как вариант, на них можно опереться, но при этом увеличить диапазон для отражения неопределенности, присущей такой оценке. С этой целью начните с расчета средней скорости команды в течение работы над предыдущим релизом. Если команда выполнила работу объемом 150 пунктов за 10 итераций, то ее средняя (среднеарифметическая) скорость равна 15 пунктам.

Прежде чем читать о том, как преобразовать этот показатель в диапазон, посмотрите на рис. 16.1. На нем показан конус неопределенности, о котором мы говорили в главе 1 «Цель планирования». Из конуса неопределенности следует, что фактический срок проекта лежит в диапазоне между 60 % и 160 % от того, чему он равен в соответствии с нашими представлениями. Поэтому, чтобы преобразовать нашу среднюю скорость в диапазон, я умножаю ее на 60 % и на 160 %. Таким образом, если наша историческая скорость равна 15, то я говорю, что скорость лежит в диапазоне от 9 до 24.

Этот диапазон может показаться большим, однако с учетом неопределенности в данной точке он приемлем. Создание диапазона подобным образом помогает проектной команде следовать совету, данному в эпиграфе к этой главе, т. е. быть примерно правой и не оказаться точно неправой. Широкий диапазон значений ожидаемой скорости облегчает попадание в него.

 

Выполнение итерации

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

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

По тем же причинам, как и в случае директора по разработке, большинству руководителей проектов полезно воздерживаться от оценок на протяжении как минимум одной итерации. Если вы оказались в такой ситуации, воспользуйтесь возможностью выполнить итерацию и измерить скорость. Затем определите диапазон относительно ее значения с помощью конуса неопределенности. Так, если вы выполните итерацию и получите скорость 15, преобразуйте ее путем умножения на 0,6 и 1,6 в диапазон 9–24.

Если команда может выполнить три итерации или более, прежде чем оценивать скорость, то у нее появляется пара дополнительных возможностей определения диапазона. Во-первых, она может просто использовать диапазон наблюдаемых значений. Допустим, команда выполнила три итерации и получила скорости 12, 15 и 16. В этом случае скорость будет лежать в диапазоне от 12 до 16.

Во-вторых, она может применить конус неопределенности. Хотя у подхода, который я собираюсь описать, нет солидной эмпирической основы, он работает и дает результаты. Вот этот подход: рассчитайте среднюю скорость для выполненных итераций. Затем для каждой итерации сместитесь на один этап вправо на конусе неопределенности. Если команда выполнила одну итерацию, используйте диапазон для этапа «начальная концепция продукта». Если команда выполнила две итерации, используйте диапазон для этапа «утвержденная концепция продукта» (от 80 % до 120 %) и т. д. Для удобства значения нужных множителей приведены в табл. 16.1.

Предположим, что команда выполнила три итерации при средней скорости 20 за период. Для трех итераций диапазон составляет 85–115 %. Это означает, что фактическая скорость к концу проекта будет, скорее всего, лежать в диапазоне от 17 до 23.

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

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

 

Прогнозирование скорости

 

Бывает, что исторические данные отсутствуют, а посвятить несколько итераций наблюдению за скоростью нет возможности. Допустим, оценка нужна для проекта, который начнется не раньше чем через 12 месяцев. Или, как вариант, проект может начаться скоро, но только после подписания клиентом договора на выполнение работы. Такие случаи характеризуются двумя ключевыми особенностями. Во-первых, с учетом желания минимизировать затраты на проект вы вряд ли будете проводить итерации по проекту, который начнется в отдаленном будущем или может не начаться вообще. Во-вторых, оценки скорости по таким проектам должны отражать высокую степень неопределенности.

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

1. Оценка количества часов, в течение которых каждый участник сможет ежедневно заниматься проектом.

2. Определение суммарного количества часов, которые будут затрачены на проект в процессе итерации.

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

4. Преобразование найденной на предыдущем этапе скорости в диапазон.

Посмотрим на примере, как работает такой подход.

 

Оценка количества доступных часов

Практически каждый из нас имеет какие-либо дополнительные обязанности, помимо своих прямых обязанностей по конкретному проекту. Все мы отвечаем на электронные письма и телефонные звонки, участвуем в корпоративных совещаниях и т. п. Количество времени, посвящаемое дополнительным обязанностям, варьирует от человека к человеку и от организации к организации. Так или иначе, участники проекта обычно не могут посвящать 100 % своего времени работе над проектом.

По моим наблюдениям и по мнению моих коллег, большинство работников, полностью занятых в проекте, могут уделять проекту от четырех до шести часов в день. Это соответствует данным о том, что участники уделяют работе над проектом от 55 % (Ganssle, 2004) до 70 % (Boehm, 1981) своего времени. Самый высокий показатель, по данным Кеннеди (Kennedy, 2003), у инженеров компании Toyota, где высокоэффективный процесс бережливого производства позволяет посвящать работе над целевым проектом до 80 % времени.

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

 

Оценка времени, доступного в итерации

Этот этап несложен: нужно просто умножить количество доступных часов в день на количество членов команды и на количество дней в итерации. Допустим, в состав команды SwimStats входит один аналитик, один программист, один администратор баз данных и один тестировщик. Четыре человека, каждый из которых работает по шесть часов в день, вместе будут отрабатывать 24 часа в день. За десятидневную итерацию они посвятят проекту примерно 240 часов.

Когда я внедрял такой подход, некоторые команды хотели учесть, помимо прочего, время отпусков, время отсутствия работников по болезни и другие перерывы в работе. Не стоит заморачиваться — это вряд ли сделает расчет более точным. Такие события — одна из причин, по которым никто не строит планы с расчетом на 100 %-ную доступность команды.

Как уделить проекту больше времени

Сколько бы часов в день члены команды ни уделяли проекту, вы вряд ли откажетесь от возможности увеличить это число. Лучший, на мой взгляд, способ добиться этого придумал Франческо Чирилло из XPLabs. Он учит команды работать с высокой концентрацией 30-минутными интервалами (Cirillo, 2005). Каждый 30-минутный интервал состоит из двух частей: 25 минут интенсивной работы, а затем пятиминутный перерыв. Эти 30-минутные интервалы называют pomodori , что в переводе с итальянского означает «помидоры». Такое название связано с использованием таймеров в виде помидоров, подающих сигнал, когда истекают 25 минут.

Чирилло представил свой метод Пьергьюлиано Босси, который документально подтвердил его успешность при работе со многими командами (Bossi, 2003; Bossi and Cirillo, 2001). Эти команды обычно планировали выполнить работу на 10 помидоров (пять часов) в день. Если вы тратите свое время менее продуктивно, чем хотелось бы, можете попробовать этот подход.

 

Развертывание историй и выбор того, что подходит

Следующий этап — развертывание историй в задачи, их оценка и повторение этого процесса до тех пор, пока не удастся заполнить расчетное количество доступных часов (в нашем случае 240 часов). Вовсе не обязательно развертывать истории в порядке приоритета. Что нам действительно требуется, так это довольно случайный набор историй. Не старайтесь, например, развернуть все одно- и двухпунктовые истории и ни одной трех- и пятипунктовой истории. Аналогичным образом не старайтесь развернуть только истории, которые связаны в основном с пользовательским интерфейсом или базой данных. Попытайтесь подобрать представительный набор историй.

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

Предположим, мы собрали запланированную команду (или создали ее аналог, если проект начнется лишь через год) и развернули некоторые истории, как показано в табл. 16.2. Если мы видим, что команда SwimStats в составе четырех человек может справиться с этим, но дополнительная работа будет ей не по силам, то останавливаемся. Эта работа объемом 221 час довольно хорошо подходит для доступных 240 часов. Наша точечная оценка скорости при этом будет равна 25.

 

Создание диапазона на основе найденной скорости

Используйте любой подход, который вам нравится, для преобразования точечной оценки скорости в диапазон. Как и прежде, я предпочитаю умножение на 60 % и 160 %. Для команды SwimStats наши расчетные 25 пунктов на итерацию дают диапазон от 15 до 40.

 

Возможный вариант для некоторых команд

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

В команде SwimStats, как видно из табл. 16.3, Юрий и Саша полностью заняты в проекте. SwimStats — единственный проект Сергея, однако он выполняет другие управленческие и корпоративные функции, которые отнимают у него определенное время. Карина делит свое время между SwimStats и другим проектом. У нее очень мало обязанностей, кроме этих двух проектов, поэтому она может уделять им почти шесть часов в день. Вместе с тем ей приходится многократно переключаться с одного проекта на другой в течение дня, и такая многозадачность сказывается на ее производительности, поэтому в таблице показано, что она уделяет проекту SwimStats только два продуктивных часа в день.

Не забывайте, зачем это делается

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

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

 

Какой подход следует использовать

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

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

• Используйте фактическую скорость команды в сходном проекте.

• Оценивайте скорость по тому объему работы, с которым вы можете справиться.

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

 

Резюме

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

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

 

Вопросы для обсуждения

1. В табл. 16.2 истории, оцениваемые одинаковым числом пунктов, имеют разную оценку задач в часах. Почему? (Если вам нужна подсказка, обратитесь к разделу «Соотнесение оценок задач с пунктами» в главе 14 «Планирование итерации».)

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

 

Глава 17

Буферизация планов для компенсации неопределенности

 

Мне нередко жалуются на то, что agile-планирование не очень хорошо работает в некоторых ситуациях. При этом обычно называют следующие условия:

• Планирование проекта осуществляется задолго до его начала.

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

• Проект передается на договорной основе из одной организации в другую.

• Требования понятны только на очень поверхностном уровне.

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

Умение составлять надежные планы в таких условиях чрезвычайно важно. Зачастую использования простого подхода, рассмотренного в предыдущих главах, недостаточно. В подобных условиях общим у всех проектов является то, что каждый из них характеризуется либо дополнительной неопределенностью, либо более серьезными последствиями в случае ошибки. Я, например, был когда-то вице-президентом по разработке программного обеспечения в компании, входящей в список Fortune 40, и календарный график для наших проектов обычно составлялся за 12–18 месяцев до их начала, когда мы верстали бюджет на следующий год. Мы, конечно, не фиксировали требования, однако должны были определять характер продукта, который будет создаваться. Несмотря на то, что представление о требованиях было расплывчатым, нам приходилось принимать обязательства первого уровня, которые позволяли составлять адекватное штатное расписание для организации. Существовала и другая неопределенность: я редко знал задолго до начала проектов, кто именно из моей команды будет над ними работать. Чаще всего исполнителей просто не было в штате.

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

Для таких случаев характерна либо повышенная неопределенность, либо более серьезные последствия ошибок в графике релиза. Как результат, полезно создавать буфер при составлении календарного графика. Буфер — это допуск на ошибку в оценке. Когда значительна неопределенность или издержки, связанные с ошибкой, создание буфера очень разумно. Буфер помогает защитить проект от влияния неопределенности. Таким образом, буферизация календарного графика проекта становится хорошей стратегией управления риском. В этой главе мы рассмотрим два типа буферов: функциональный буфер и буфер календарного графика (временной буфер).

 

Функциональный буфер

Прошлым вечером я отправился в продовольственный магазин со списком продуктов из 37 пунктов. В моем распоряжении было лишь полчаса, чтобы купить нужные продукты и вернуться домой, поскольку я хотел посмотреть баскетбольный матч, который начался в это время. Как обычно, я начал с одного конца магазина и стал продвигаться к другому. Я шел вдоль полок, а мое внимание было сконцентрировано примерно на 20 товарах, которые нам требовались больше всего. Я знал: если приду домой без молока, хлеба или нарезки из индейки, то в перерыве мне придется снова идти в магазин. Если же я забуду что-то менее важное, то моя жена смирится с этим, у моих дочек будет что поесть, а у меня — возможность спокойно посмотреть баскетбол.

Буферизация проекта с помощью функций точно такой же процесс. Клиентам говорят: «Мы реализуем все функции в этом пакете, а в идеале некоторые функции в том пакете». В agile-проекте функциональный буфер создается очень просто. Сначала клиент выбирает всю абсолютно обязательную работу. Оценки этой работы суммируются. Данная работа представляет собой минимум, который может войти в релиз. Затем клиент выбирает еще 25–40 % работ ближе к узкоспециализированному концу диапазона для проектов с более высокой неопределенностью или меньшей устойчивостью к риску невыполнения календарного графика. Оценки этих работ добавляют к первоначальной оценке и получают суммарную оценку проекта. После этого составляют план проекта как обычно, предусматривая поставку полного набора функций, однако при этом часть работы является опциональной и выполняется только в том случае, если позволяет время. Опциональная работа выполняется в последнюю очередь и всегда после завершения обязательной.

Для лучшего понимания того, как это работает, предположим, что владелец продукта идентифицировал работу объемом 100 пунктов как обязательную. Каждая из отобранных историй предполагает выпуск продукта, который будет хорошо принят рынком. Владелец продукта затем выбирает дополнительные 30 % работы, идентифицируя пользовательские истории, оцениваемые еще в 30 пунктов. Эти истории добавляются в проект как опциональная работа. Ожидаемый суммарный размер проекта теперь составляет 130 пунктов. Используя методы, описанные в главе 16 «Оценка скорости», команда определяет, что ее скорость составит 10 пунктов на однонедельную итерацию. В план проекта закладывают 13 итераций (130 / 10). Если все идет хорошо, то обязательная работа выполняется за первые 10 итераций, а оставшиеся три итерации посвящают опциональным функциям.

Процесс функциональной буферизации согласуется с agile-процессом, называемым «метод разработки динамических систем (dynamic systems development method — DSDM)». В DSDM-проектах требования разделяют на четыре категории: обязательные, желательные, опциональные, ненужные. К обязательным может быть отнесено не более 70 % запланированных функций в проекте. Таким образом, в DSDM-проектах создается функциональный буфер, эквивалентный 30 % срока проекта.

 

Временной буфер

Допустим, мне нужно отправиться в аэропорт и успеть на рейс в Италию. (Ну вот, сплоховал! Можно было придумать место и получше.) Для авиаперелетов характерно очень жесткое расписание. Самолет улетит в любом случае, со мной или без меня. В план перемещения от дома до соответствующей посадочной зоны в аэропорту мне необходимо заложить достаточно времени, чтобы точно успеть на самолет, но не столько, чтобы оказаться в аэропорту за три дня до вылета.

Я продумываю все этапы: дорога в аэропорт, поиск места на парковке для автомобиля, регистрация и сдача багажа, прохождение пункта досмотра. Я прикидываю, сколько времени мне потребуется на это, если все пройдет хорошо, и решаю, что на все уйдет 70 минут. Иначе говоря, определяю, сколько это должно занять. На деле на всё про всё может уйти даже чуть меньше, но нет никакой гарантии, что не потребуется намного больше. На шоссе может случиться авария, парковка может оказаться забитой, у стойки регистрации может образоваться длинный хвост, как, впрочем, и у пункта досмотра. В общем, времени может потребоваться заметно больше. Планировать, что все пойдет наперекосяк во время одной и той же поездки, не стоит. Однако эта поездка важна для меня и мне не хочется опоздать на самолет, поэтому я должен добавить какой-то запас к 70 минутам, в которые можно уложиться, если все будет нормально.

Скажем, я решил отправиться в аэропорт за 100 минут до вылета самолета. Если все идет хорошо, у меня останется 30 минут, чтобы побродить по аэропорту, а это не самое плохое занятие. Если обстоятельства сложатся совсем удачно (на шоссе я попаду в зеленую волну, на парковке найду место в первом ряду, и никого не будет у стойки регистрации или в пункте досмотра), то в аэропорту в моем распоряжении, возможно, окажется целых 40 свободных минут. Но если я застряну в пробке или долго простою в очереди на регистрацию, дополнительного времени, скорее всего, хватит, чтобы вовремя попасть на самолет. Дополнительные 30 минут — это мой буфер в календарном графике, который защищает своевременное завершение проекта в целом (достижение аэропорта).

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

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

 

Отражение неопределенности в оценках

 

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

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

Наиболее вероятное время выполнения задачи на рис. 17.1 находится в том месте, где кривая достигает пика. В целом, однако, вероятность выполнения задачи к этому сроку составляет менее 50 %. Это известно потому, что слева от пика находится менее 50 % площади под кривой. Если бы разработчик дал оценку, соответствующую пику на рис. 17.1, он, скорее всего, не выполнил бы работу к названному сроку. Более наглядно это представлено на рис. 17.2, где изображена кумулятивная вероятность завершения задачи в сроки, отложенные по горизонтальной оси, или раньше них.

Если на рис. 17.1 показана вероятность завершения задачи в конкретное время, то на рис. 17.2 представлена вероятность завершения задачи в это время или ранее. В процессе оценки и планирования это более важно для нас, чем вероятность завершения работы в отдельно взятый день (как показано на рис. 17.1).

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

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

Первое число для каждой задачи (в светлом прямоугольнике) — оценка продолжительности выполнения задачи с 50 %-ной вероятностью. По моим предположениям, одна половина задач потребует больше времени, а другая — меньше. Второе число (в затемненном прямоугольнике) — это дополнительное время, необходимое для достижения 90 %-ной вероятности. Дополнительное время, представляющее собой разницу между 50 %-ной и 90 %-процентной оценками, называют локальным запасом. Мы нередко добавляем локальный запас к оценке, когда хотим быть более уверенными в выполнении задачи. В нашем случае я думаю, что на поиски ключей мне может понадобиться от одной до шести минут. Я могу добраться до аэропорта через 45–75 минут.

Сложение оценок с 50 %-ной вероятностью дает мне ожидаемый срок, равный одному часу и 10 минутам. Однако, если я выйду из дома так близко ко времени вылета, малейшая задержка приведет к опозданию на рейс. Вместе с тем сложение оценок с 90 %-ной вероятностью дает в сумме два часа 50 минут. Мне совершенно не хочется выезжать почти за три часа до вылета, поскольку вероятность того, что все пойдет наперекосяк, очень мала. Что мне реально хочется получить, так это план проекта, подобный приведенному на рис. 17.4.

План на рис. 17.4 строится на основе оценок с 50 %-ной вероятностью, к которым прибавляется проектный буфер. Такой план намного разумнее, чем тот план, который полностью построен на суммировании оценок с 50 %-ной или 90 %-ной вероятностью. В плане на рис. 17.4 защищается только конечный срок, который имеет принципиальное значение: общий срок проекта. Поскольку совершенно не важно, потребует ли та или иная задача на пути в аэропорт больше времени, мне не нужно создавать буфер для обеспечения своевременного завершения задач. Это позволяет мне сконструировать календарный график, где нет локального запаса для отдельных задач, зато часть этого запаса добавляется в буфер, защищающий календарный график в целом. Обратите внимание на то, что календарный график с буфером на рис. 17.4 занимает только один час 58 минут — почти на час меньше, чем график, полученный в результате суммирования оценок с 90 %-ной вероятностью.

Еще лучше то, что перенос локального запаса в буфер проекта в целом позволяет избежать влияния закона Паркинсона и синдрома студента. Как мы знаем из главы 2 «Почему планирование дает неудовлетворительные результаты», закон Паркинсона гласит, что работа растягивается так, чтобы занять все отведенное на нее время. Синдром студента (Goldratt, 1997) — это склонность откладывать дела на последний момент, что мешает их успешному завершению, например начинать работу над курсовым проектом в колледже за три дня до срока сдачи. Устраняя проблемы, связанные с законом Паркинсона и синдромом студента, такой подход делает вероятность выполнения более короткого календарного графика с буфером выше, чем вероятность выполнения более длинного графика.

Первое, что требуется для создания временнóго буфера, это пересмотр нашего процесса оценки таким образом, чтобы обеспечить генерирование двух оценок для каждой пользовательской истории или функции. Точно так же, как и в случае поездки в аэропорт, нам нужны оценки с 50 %-ной и 90 %-ной вероятностью. Получить их довольно просто: когда команда соберется для проведения оценки, начните с 50 %-ной оценки первой истории. Затем дайте 90 %-ную оценку этой истории, прежде чем переходить к следующей истории или функции.

 

Определение размера буфера проекта

Размер буфера проекта на рис. 17.4 определен как 53 минуты. Как я получил его? На основе 50 %-ных и 90 %-ных оценок для этого проекта, как показано на рис. 17.4. Прелесть присвоения двух оценок каждой пользовательской истории в том, что цифры предельно ясно указывают на уровень риска срыва графика, связанный с каждым элементом. Например, если одну историю оценивают в 3–5, а вторую в 3–10, то мы знаем, что вторая история привносит в проект более значительный риск срыва графика. Буфер проекта должен иметь такой размер, чтобы компенсировать риск срыва графика, связанный с запланированной работой. Возьмем экстремальный вариант: если вы составляете календарный график проекта, то вам потребуется меньший буфер проекта для задач с оценкой 3–7 по сравнению с задачами, которые имеют оценку 3–100. Если проект включает в себя трехпунктовые задачи, который могут обернуться 100-пунктовыми, то проекту нужен более значительный буфер, чем при задачах, которые в наихудшем случае могут потянуть только на 10 пунктов. Иначе говоря, спред между 50 %-ными и 90 %-ными оценками влияет на размер буфера проекта.

Поскольку наши оценки представляют собой пункты для каждого элемента при вероятности 50 % и 90 %, разница между ними равна примерно двум стандартным отклонениям. Стандартное отклонение для каждого элемента равно (wi — ai) / 2, где wi представляет наихудший случай (90 %-ную оценку) для истории i, а ai — средний случай (50 %-ную оценку) для той же истории. Нам нужно, чтобы буфер проекта защищал проект в целом на таком же 90 %-ном уровне, как и у каждой задачи с ее 90 %-ной оценкой. Это означает, что наш буфер проекта должен составлять два стандартных отклонения, которые определяются по следующей формуле:

где σ — стандартное отклонение. Эту формулу можно упростить до такого вида:

Посмотрим, как эта формула применяется для определения размера временнóго буфера. Предположим, что наш проект включает в себя шесть пользовательских историй, представленных в табл. 17.2, и что каждая история имеет 50 %-ную и 90 %-ную оценки. Оценки могут быть как в пунктах, так и в идеальных днях. В последней колонке табл. 17.2 приведен результат расчета, в котором из наихудшей (90 %-ной) оценки истории вычитают среднюю (50 %-ную) оценку этой истории, а разность возводят в квадрат. Для первой истории, например, результат составляет (3–1)2 = 4. Временной буфер — это квадратный корень из суммы этих квадратов. Временной буфер в нашем случае равен квадратному корню из 90, или 9,4, которые мы округляем до 9. Общая продолжительность проекта представляет собой сумму 50 %-ной оценки и буфера проекта, в нашем случае 17 + 9 = 26.

Буфер, рассчитанный в табл. 17.2, интуитивно понятен. Наибольший вклад в размер буфера вносит та пользовательская история (первая история), которая имеет наибольшую неопределенность (разница в восемь пунктов между 50 %-ной и 90 %-ной оценками). В то же время история, где неопределенность отсутствует (последняя история), не добавляет в буфер ничего.

Создание буфера для календарного графика в одних случаях приводит к увеличению длины проекта на одну или несколько итераций, а в других — нет. Чаще всего приводит. Допустим, команда в нашем примере спрогнозировала свою скорость как девять пунктов на итерацию. Если проект был оценен в 17 пунктов (сумма 50 %-ных оценок), то следовало бы ожидать завершения проекта за две итерации. Однако при включении в проект буфера полный объем работы становится равным 26 пунктам, для реализации которых потребуются три итерации при скорости команды, равной девяти пунктам.

 

Более простой способ расчета буфера

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

Хотя такой расчет значительно проще, у него есть серьезный недостаток — в нем не учитывается фактическая неопределенность конкретных пользовательских историй в проекте. Допустим, у нас есть две истории, каждая из которых оценена в пять пунктов. Обе они вносят одинаковый вклад в буфер проекта (половину своего размера, или по 2,5 пункта). Это правило сохраняется несмотря на то, что одна из этих историй может иметь 90 %-ную оценку 100, а другая — 10.

 

Правила определения размера буфера

Независимо от того, что вы предпочитаете, метод квадратного корня из суммы квадратов или 50 %-ный подход, при определении размера буфера необходимо руководствоваться следующими дополнительными правилами, вытекающими из рекомендаций Лича (Leach, 2000).

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

• На буфер проекта должно приходиться не менее 20 % общего срока этого проекта. Буфер меньшего размера не всегда обеспечивает адекватную защиту проекта в целом.

 

Комбинирование буферов

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

Именно сочетание функционального и временнóго буферов обеспечивает реальную защиту проектов от неопределенности. Взгляните на три проекта, показанные на рис. 17.5. В секции а) представлен проект, где необходимо поставить заказчику четко определенный набор функций, но можно варьировать сроки. В секции b) представлена противоположная ситуация: проект, где дата завершения фиксирована, но допускается гибкость в отношении реализованных функций. В секции с) видно, что создание и функционального, и временнóго буфера позволяет команде выдержать дату поставки и одновременно реализовать минимальный набор функций. При создании плана релиза наша цель заключается в использовании буферов таким образом, чтобы команда могла принять эти виды обязательств.

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

1. Один-два дополнительных человека для создания буфера по персоналу в небольшом проекте почти всегда вносят прямой вклад в срок проекта. Увеличение штата с 30 до 33 разработчиков вряд ли заметно повысит производительность, если вообще повысит. Если же штат увеличивается с четырех разработчиков до пяти, то производительность практически наверняка вырастет.

2. Очень трудно создавать буферы для чего-то небольшого. Когда в проекте, где занято 30 человек, создается резерв из трех работников и полный штат увеличивается до 33, мы получаем 10 %-ный буфер по персоналу. Аналогичный буфер для проекта, в котором заняты три человека, составит всего 0,3 разработчика. Понятно, что часть человека не добавишь в проект.

 

Временной буфер — это не раздувание сроков

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

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

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

 

Ограничительные оговорки

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

• При добавлении временнóго буфера используйте подход с двумя оценками, описанный в этой главе, а при использовании одной оценки следите за тем, чтобы она была 50 %-ной. Добавление временнóго буфера к и без того пессимистичным 90 %-ным оценкам приведет к чрезмерному удлинению сроков.

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

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

 

Резюме

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

Наиболее распространенными являются функциональные и временны́е буферы. Функциональный буфер создается, когда требования к продукту приоритизированы и признано, что реализовать можно не все функции. В DSDM-процессе, например, рекомендуется считать 30 % работ опциональными, создающими функциональный буфер для проекта. Когда время истекает, календарный график все равно можно выдержать, отказываясь от реализации элементов функционального буфера.

Временной буфер, в свою очередь, создается путем включения в календарный график дополнительного времени с учетом неопределенности, присущей размеру команды. Функциональный буфер можно сконструировать на основе присвоения каждой пользовательской истории двух оценок — с 50 %-ной и 90 %-ной вероятностью. Формула «извлечение квадратного корня из суммы квадратов» позволяет найти подходящий размер временнóго буфера.

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

 

Вопросы для обсуждения

1. Дает ли затрата дополнительных усилий на расчет временнóго буфера какие-либо выгоды в условиях вашей организации?

2. Предусмотрены ли в вашем текущем проекте буферы для компенсации какого-либо типа неопределенности? Если да, то какие? Если нет, то какие типы буферов были бы наиболее полезными?

3. Есть ли признаки проявления закона Паркинсона или синдрома студента в вашей организации? Что еще, помимо предложений, представленных в этой главе, вы можете предпринять для снижения влияния этого закона и синдрома?

 

Глава 18

Планирование проекта с участием нескольких команд

 

Нередко говорят, что agile-команды состоят не более чем из 7–10 разработчиков. Команды такого размера могут выполнить довольно большой объем работы, особенно при использовании agile-процесса, который открывает возможности для повышения производительности и поощряет ее повышение. Вместе с тем встречаются проекты, к которым хотелось бы привлечь более крупную команду. В таких случаях вместо создания команды из 100 человек agile-подход предполагает создание нескольких небольших команд. В agile-проекте может участвовать десяток небольших команд вместо одной огромной команды из 100 человек.

В этой главе мы возьмем то, что узнали в предыдущих главах, и применим к задаче планирования проекта, в котором участвуют несколько команд. Для планирования крупного проекта с участием нескольких команд необходимо:

1. Принять общую базу для оценок.

2. Быстрее добавлять детали в пользовательские истории.

3. Выполнять опережающую разработку планов.

4. Включать в план поддерживающие буферы.

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

 

Принятие общей базы для оценок

Хотя было бы хорошо предоставить каждой команде возможность по своему усмотрению выбирать, в чем проводить оценку — в пунктах или идеальных днях, в большинстве случаев проекты с участием нескольких команд выигрывают от оценки в одних и тех же единицах и установления их базового смысла. Представьте, как трудно было бы предсказывать, сколько еще времени потребуется для реализации набора пользовательских историй, если бы одна их часть оценивалась в идеальных днях, а другая — в пунктах. Хуже того, представьте, насколько все усложнилось бы, если бы одна команда оценила набор историй в 20 пунктов, а другая — в 100 пунктов.

В начале проекта команды должны встретиться и определить, что они будут использовать, пункты или идеальные дни. Затем им нужно установить общую базу для оценок с тем, чтобы оценка одной команды была идентична оценке другой команды, если бы эта работа попала к ней. Каждая пользовательская история оценивается только одной командой, но оценки должны быть эквивалентными, независимо от того, какая команда оценивает работу.

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

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

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

 

Более быстрое добавление деталей в пользовательские истории

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

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

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

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

 

Опережающее планирование

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

Информация по национальным рекордам и рекордам по возрастным группам хранится в базе данных на удаленном объекте национальной ассоциации по плаванию. Доступ к этой базе данных не так прост, как хотелось бы командам, и национальная ассоциация собирается сменить поставщиков баз данных в ближайший год-два. По этой причине владелец продукта и команды разработчиков согласились с тем, что нужно разработать API (интерфейс прикладного программирования) для доступа к базе данных. Это должно значительно упростить переход к другому поставщику баз данных. Первоначальные пользовательские истории и их оценки приведены в табл. 18.1.

Скорость оценивается как 20 пунктов на итерацию для одной и другой команды. Поскольку объем работ составляет 110 пунктов, команды должны поставить полную функциональность за три итерации. Вместе с тем 30 пунктов приходятся на разработку API, а еще 40 пунктов (три последние истории в табл. 18.1) можно реализовать только после разработки API. Это приводит к такому распределению работ, которое представлено на рис. 18.1, где взаимозависимость команд обозначена стрелкой между реализацией API первой командой и работой над индивидуальными результатами, выполняемой второй командой.

Возможно, вы помните, что в главе 13 «Основные аспекты планирования релиза» я рекомендовал показывать в плане релиза детали только следующих двух итераций. Объясняется это тем, что такой подход нередко достаточен для поддержки взаимозависимостей, с которыми имеют дело многие команды. Когда нескольким командам приходится работать вместе, план релиза следует обновлять с тем, чтобы показывать и координировать работу в следующих двух или трех итерациях. Точное число итераций, конечно, зависит от частоты и серьезности взаимодействий команд. После завершения итераций связанные с ними детали удаляют из плана. Таким образом, план релиза становится скользящим опережающим планом, который всегда отражает ожидания относительно нескольких новых итераций. Лауфер (Laufer, 1996) называет это «заглядывание вперед».

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

 

Включение в план поддерживающих буферов

 

Для большинства команд в большинстве ситуаций скользящий опережающий план вполне уместен. Однако бывает, что взаимодействия команд настолько сложны или часты, что простого скользящего опережающего планирования, описанного в предыдущем разделе, недостаточно. В таких случаях первое, что нужно сделать, это попытаться сократить количество взаимодействий до уровня, при котором скользящее опережающее планирование станет реальным. Если добиться этого не удается, попробуйте включить в итерацию поддерживающий буфер, который даст свободу, необходимую другим командам. Поддерживающий буфер, как и временной буфер, описанный в предыдущей главе, защищает своевременную поставку набора новых возможностей. Это довольно сложный способ сказать простую вещь: если вашей команде требуется что-либо от моей команды к 8:00, то моей команде не следует планировать завершение этого на 7:59. Иначе говоря, нам нужен план вроде того, что представлен на рис. 18.2.

На рис. 18.2 поддерживающий буфер вставлен между завершением API командой 1 и началом работы команды 2 с использованием API над пользовательской историей, связанной с данными по индивидуальным результатам. Поддерживающий буфер защищает дату начала работы над историей, связанной с данными по индивидуальным результатам, от задержек в реализации API.

Чтобы включить поддерживающий буфер в план релиза, нужно всего лишь временно планировать работу с расчетом на более низкую скорость команды, которая поставляет определенную возможность другой команде. В случае, представленном на рис. 18.2, усилия команды 1 равномерно делятся между завершением API и поддерживающим буфером так, чтобы гарантировать команде 2 возможность приступить к работе над индивидуальными результатами с самого начала третьей итерации. Это не означает, что команда 1 получает возможность не торопиться в процессе второй итерации. В действительности от нее ожидают, что она выполнит связанную с API работу в 10 пунктов, использует только часть буфера и начнет работать над пользовательской историей, связанной с национальными рекордами, уже во второй итерации.

 

Что именно буферизируется?

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

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

 

Определение размера поддерживающего буфера

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

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

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

 

Но ведь это уйма работы

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

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

 

Резюме

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

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

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

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

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

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

 

Вопросы для обсуждения

1. Как вы устанавливаете общую базу для оценок в проектах с участием нескольких команд?

2. Насколько значительна взаимозависимость команд в вашем текущем проекте? Какие приемы из описанных в этой главе являются самыми действенными?