English Version

Agile в неравенствах

Автор: Александр Якима (www.enter-agile.com)

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

трудозатраты != результаты != ценность

Выглядит очень просто. Попробуем посмотреть, что стоит за этой формулой... по частям:

1. трудозатраты != результаты. Это неравенство в первую очередь относится к команде разработчиков. Тем более оно как раз особо важно для заказной разработки, или даже лучше будет сказать: контекст этого неравенства является в области контроля команды разработчиков, в отличие от неравентсва №2 (см. ниже). Это неравенство оипсывает правильную психологию гибкой команды, для которой важен только результат - они его регулярно достигают посредством инкрементов итераций и соответсвенно с практической позиции знают, что методы и трудозатраты, необходимые для достижения результата, чаще всего оказываются совсем не такими как казалось по-началу.
Несколько типичных иллюстраций:

Технический аванс vs. технический долг. Есть у многих разработчиков такая слабость: при имплементации фичи дойдя до определенного слоя системы начать "закладываться" под другие гипотетические фичи: "раз уж я здесь, то сделаю больше... а то что это за слой такой - всего два класса...". Эффективным будет на самом деле оставить минимальное минимальным, а с точки зрения того, насколько нужно "закладываться" под кое-какую общность - исходить из простого правила: всегда лучше сделать, получив на выходе результат, имеющий ценность для конечного пользователя (читай - работающий продукт) и таким образом взять технический долг, который потом "отдается" в форме рефакторинга, чем брать технический аванс и не знать, что с ним потом делать по отношению к пользователю. Так вот, реализованные фичи - это уже результат независимо от того, сколько трудозатрат на нее потрачено, а слой системы - это слой системы и не более, его пользователь не то что применить не сможет, но даже объяснить ему не сможете, что это такое. Итак, сделав слой "наугад" команда а) на 90% рискует ошибиться и б) лишает себя дополнительных опций в принятии технических решений в будущем - а это даже хуже. Итак, добиваемся результата любой ценой, оставляя, возможно, за собой технический долг, который в последствии отдаем в форме рефакторинга.

Перфекционизм. Почему-то часто принято считать, что перфекционизм как-то положительно связан с профессионализмом. Нет, есть конечно несколько форм положительного проявления перфекционизма, например: например, в постоянной поддержке бэклога, или в том, чтобы не давать дефектам переходить в следующую итерацию и т. д. Но что на самом деле обычно является предметом усердствований перфекциониста? Именно так: как писать юнит-тесты, как писать код, что выносить, а что нет в конфигурационные файлы и т. д. У всего этого есть одно общее свойство - акцент на низкоприоритетных вещах. Вроде бы и лишних "движений" по слоям не делается, как в предыдущем случае, вроде бы появился только нужный код, но увы, на его "полировку" уходит уйма усилий в то время, когда нужно всего лишь грубо отшлифовать. Тут нельзя не вспомнить советскую 34-ку, грубую, везде похабно подвареную, но достаточно надежную и, самое главное - дешевую в производстве, по сравнению со сверхкачественными Тиграми, которые требовали много дорогих как сырьевых, так и человеческих ресурсов. Советский танк тогда выиграл войну своей легкостью в производстве и поддержке, это прекрасный исторический пример, свидетельствующий о здоровом расчете: место танка - на поле боя, а не на автошоу.

2. результаты != ценность. Допустим теперь для простоты, что мы имеем дело с идеальной командой разработчиков, всецело понимающей и на практике руководствующейся неравнеством №1. И все же, несмотря на нацеленность на результат, результат этот может не нести должной ценности конечному пользователю - и действительно существует немало примеров прекрасной реализации релизов продукта, никому не нужного, как оказывается в последствии. "Это не проблема разработчиков", - скажут разработчики и будут почти правы, так как этот пункт почти полностью относится к обязанностям продакт-оунера. Это неравенство какраз выражает ту простую мысль, что правильное задание приоритетов - кардинально сложная задача. Если неравенство №1 "срабатывает" на уровне итерации, то неравенство №2 - это уровень релиза, так как нет иного эффективного способа эффективно валидировать свои гипотезы о приоритности фич, как посредством частых релизов и активного сбора фидбеков от пользователей. Тут и становится понятным использованное нами наречие "почти": команда должна научиться релизить часто. Часто - понятие относительное, но если разработка производится командой из 5 - 30 человек, полностью покрывающих разработку системы, то 6-8 недель - абсолютно достижимый и даже весьма рекомендуемый таймбокс для релиза.

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

Одним слайдом: Анатомия гибкой итерации

Автор: Александр Якима (www.enter-agile.com)

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

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

Agile-Стоматолог

Автор: Александр Якима (www.enter-agile.com)

В 2007 году один из разработчиков на моем проекте посоветовал стоматолога. С тех пор я стоматолога не менял. И не собираюсь. Почему? Потому что этот стоматолог 100% ориентирован на качественное удовлетворение потребности "пользователя". Расскажу подробнее и мы увидим явные параллели с гибкой разработкой.


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

Комментарий. Это мечта любого продакт-оунера. Команда исправно доставляет инкременты итераций, действительно работающие, и каждый раз ожидает от него простого "ДА" (принято) или "НЕТ" (не принято). Квинтэссенция всего - приемка релиза. Однако типичная расхлябаность и отсутствие элементарной дисциплины оставляют от гибкой команды одно название (см. У Вас Agile? Проверим?..). Очень часто ситуация усугубляется тем, что на проекте нет выделеной роли "продакт-оунер". Тогда следует кому-то в команде это бремя на себя принять, а именно - роль прокси продакт-оунера. Тема проксирования заслуживает целой книги, мы к ней обязательно вернемся в последующих постах. Однако важно помнить следуюющее простое правило: без продакт-оунера, делающего систематическую приемку выхлопа каждой итерации, это не Agile.

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

Комментарий. Команда должна не просто выкатывать комок софта на демо и на этом все. Нет. Так команда получит только поверхностный фидбэк от продакт-оунера. Чтобы основательно понять, в каком состоянии предлагаемый билд итерации, команда должна предоставить продакт-оунеру следующие две вещи:
1) "Алгоритм" полноценной приемки. Обяснить как "локализовать нервные окончания".
2) Время, достаточное для выполнения офф-лафн приемки.
Последнее означает в оптимальном случае (и это действительно хороший стиль работы), что до следующего демо у продакт-оунера будет свободный доступ к текущему билду; иными словами - держать инкремент предыдущей итерации доступным всю текущюю итерацию, пока не появится новый инкремент.

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

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

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

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

Берегите зубы!

Основы пользовательских историй. Часть 4.


Дин Лэффингуэл (Dean Leffingwell, blog), Пит Беренс (Pete Behrence)

Перевод: Александр Якима (www.enter-agile.com)

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

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

Не существует какой-либо установленной процедуры разбиения пользовательских историй на куски, вместимые в рамки итерации, кроме как общих положений о том, чтобы стори предоставляла вертикальный срез, определенный кусок, ценный для пользователя, проходящий систему насквозь. Однако, базируясь на недавней работе Ричарда Лоренца (Richard Lawrence), мы рекомендуем применять соответствующий набор из десяти общих паттернов разбиения пользовательской истории, как это показано в Таблице 1[11]:










































































1. По последовательностям действий. 

Определить конкретные шаги, выполняемые пользователем в рамках последовательности, и тогда реализовать последовательность поэтапно.

Как энергокомпания я хочу изменять и публиковать тарифные планы потребителю

...Я могу публиковать тарифные планы на домашний дисплей

...Я могу послать сообщение на Интернет-портал потребителя

...Я могу опубликовать таблицу тарифов на смарт-термостате потребителя


2. По вариации бизнес правил. 

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

Как энергокомпания я могу упорядочивать потребителей по демографическому признаку

...упорядочивать по почтовому индексу

...упорядочивать по домашней демографии

...упорядочивать по уровню потребления энергии


3. По основным трудозатратам. 

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

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

...Я хочу использовать Временной тариф [12]

...Я хочу использовать Предоплатный тариф

...Я хочу подписаться на Пиковый тариф [13]


4. По простоте / сложности. 

Когда команда обсуждает пользовательскую историю и она, кажется, становится все объемней и объемней (“А как насчет x? А думали ли вы об y?”), следует остановиться и спросить себя “какой наипростейший вариант мог бы сработать?” Зафиксируйте эту простейшую версию в качестве первой стори, и тогда уже сможете разбить все вариации и сложные детали в отдельные пользовательские истории.

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

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

...реагировать на непредвиденные изменения


5. По вариациям данных. 

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

Как энергокомпания я могу отсылать сообщения потребителям

...на английском

...испанском

...арабском и т. д.


6. По методам ввода данных. 

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

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

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

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


7. Отсрочка качеств системы. 

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

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

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

...показать настоящие данные счетчика в реальном времени


8. По операциям (пример: CRUD [14]). 

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

Как пользователь я могу управлять своей учетной записью

...Я могу создать учетную запись

...Я могу редактировать установки учетной записи

...Я могу приостановить учетную запись

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


9. По сценариям использования. 

Если сценарии разрабатывались для представления сложных взаимодействий вида “пользователь-система” или “система-система”, то стори часто можно разделить соответственно отдельным под-сценариям.

Я хочу подписаться на программу энергосбережения через розничного дистрибьютора.

Сценарий / Стори №1 (оптимистичный сценарий): Сообщить энергокомпании, что у пользователя есть оборудование


Сценарий / Стори №2: Энергокомпания обеспечивает оборудование и данные и уведомляет потребителя.


Сценарий / Стори №3 (альтернативный сценарий): Обработать ошибки при валидации данных.


10. Запустить спайк. 

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



Таблица 1. Десять паттернов разбиения пользовательской истории

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


ПРОДОЛЖЕНИЕ СЛЕДУЕТ...


----------------------------------------

Литература

Cohn, Mike. 2004. User Stories Applied: For Agile Software Development. Boston, MA: Addison-Wesley.
Martin, Robert. 2009. Clean Code: A Handbook of Agile Software Craftsmanship. Boston: MA: Pearson Education.
Poppendieck, Mary, and Tom Poppendieck. 2007. Implementing Lean Software Development: From Concept to Cash. Boston, MA: Addison-Wesley.
Jeffries, Ron. 2001, August. “Essential XP: Card, Conversation, and Confirmation.” XP Magazine.

----------------------------------------

11. Адаптировано из статьи Ричарда Лоренца: http://www.richardlawrence.info/2009/10/28/patterns-for-splitting-user-stories/

12. Примечание автора перевода: в США потребители электроэнергии могут воспользоваться временным тарифом (time-of-use pricing), который предполагает разные тарифы в разные периоды времени (обычно года; тарифы заранее известны потребителю) и, таким образом, позволяет оптимизировать объем платы за энергию.

13. Примечание автора перевода: Пиковый тариф (Critical Peak Pricing) отражает отношение к себестоимости энергии и позволяет потреблять по “оптовым” тарифам в момент высокой загруженности сети.

14. Примечание автора перевода: Create Read Update Delete – Создание Чтение Обновление Удаление, - сокращенное название базовых функций управления данными.

Основы пользовательских историй. Часть 3.

Дин Лэффингуэл (Dean Leffingwell, blog), Пит Беренс (Pete Behrence)

Перевод: Александр Якима (www.enter-agile.com)


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


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

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

Поэтому,
инвестировать усилия в качественные стори, хоть и в последний ответственный момент, является стоящим занятием для команды. Билл Вейк (Bill Wake), ввел в оборот аббревиатуру INVEST[7], чтобы описать атрибуты хорошей пользовательской истории[8]:

Independent (Независимая)
Negotiable (Обсуждаемая)
Valuable (Полезная)
Estimable (Эстимируемая)
Small (Компактная)
Testable (Тестируемая)

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


Независимость

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

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

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


1) Как администратор я могу установить правила безопасности пользовательских паролей так, что пользователи будут обязаны создавать и поддерживать безопасные пароли, поддерживая безопасность системы.
2) Как пользователь я должен следовать правилам безопасности паролей, установленным администратором, чтобы поддерживать безопасность моей учетной записи.


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

Путем пересмотра пользовательских историй (и архитектуры системы) мы можем удалить зависимости переразбив стори иным способом – в нашем случае по типу политики безопасности и соединяя воедино установку политики и ее применение в каждой стори:


1') Как администратор я могу установить период истечения действия пароля, таким образом пользователи будут обязаны периодически менять пароли.
2') Как администратор я могу установить характеристики сложности пароля, так что пользователи будут обязаны создавать пароли, которые сложно подобрать.


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



Обсуджаемость

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

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

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


Польза

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

Типичный вызов, с которым сталкиваются команды – научиться писать небольшие, инкрементальные пользовательские истории, подходящие для эффективной доставки ценности. Традиционные подходы запечатлели в нас алгоритм функциональной разбивки требований на технические компоненты. Этот подход “технического наслоения” при разработке систем замедляет доставку до тех пор, пока все слои не будут соединены воедино в результате многочисленных итераций. Вейк[9] (Wake) предлагает свое видение скорее вертикального, чем технического (горизонтального), наслоения:


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


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

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


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


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


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


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


Произвести рефакторинг системы логирования ошибок.


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


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


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


Эстимируемость

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

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

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


Компактность

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


Увеличение пропускной способности

Как известно из теории массового обслуживания, более компактные пакеты проходят сквозь систему быстрее. Это один из ключевых принципов бережливого производства и отражен в законе Литтла (Little):



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

Более того, когда система загружена полностью, она может стать нестабильной и проблема может нагромождаться. В сильно перегруженных системах большие пакеты двигаются сквозь систему непропорционально медленно, так как пропускная способность падает. (Представьте себе шоссе в час пик. У мотоцикла шансов нормально передвигаться значительно больше, чем у легковых автомобилей и грузовиков – значительно легче маневрировать компактными объектами при движении в нагруженной системе.) Поскольку команды разработчиков обычно заняты почти на полную нагрузку, а то и выше (80-120%), они также попадают в “час пик”.

Когда загрузка достигает порядка 80% и выше, большие объекты увеличивают продолжительность цикла (замедляют) в значительно большей степени, чем меньшие объекты. Более того, вариация продолжительности цикла увеличивается, то есть становится труднее предсказать, когда пакет сможет на самом деле покинуть систему – иллюстрация этому представлена на Рисунке 1 ниже[10]. В свою очередь, эта низкая предсказуемость разрушает планы, обязательства и доверие к команде.



Рисунок 1. У больших пакетов больше продолжительность цикла и выше вариация.



Уменьшение сложности

Более компактные пользовательские истории проходят сквозь процесс разработки быстрее не только из-за их пропорционального объема, но и из-за меньшей сложности, а сложность нелинейно зависит от объема. Это лучше всего наблюдается в тестировании, где разветвленность системы тестов, необходимых для валидации функциональности, растет экспоненциально по отношению к объему самой функциональности. Это соответствует рекомендации по разработке чистого кода, а именно, Роберт Мартин [Martin 2009] предлагает следующие правила для функций системы:

Правило 1: Реализуйте что-то одно

Правило 2: Следите, чтобы объем задачи был небольшим

Правило 3: Сделайте ее еще меньшей


Это одна из основных причин, почему последовательность Фибоначчи (то есть 1, 2, 3, 5, 8, 13, 21, ...) столь эффективна при эстимировании пользовательских историй – оценка трудозатрат растет нелинейно с ростом объема задачи.


О соотношении объема и независимости

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


Тестируемость

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

Чтобы удостовериться в том, что стори не попадут в итерацию, если они не способны из нее выбраться (то есть быть успешно оттестированными), много гибких команд на сегодняшний день применяет подход: “сначала тесты”. Это берет начало в XP-сообществах, использующих Разработку через тестирование (TDD) – практику написания автоматизированных юнит тестов перед написанием кода, который должен этим тестам удовлетворять.

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

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


ПРОДОЛЖЕНИЕ СЛЕДУЕТ...

--------------------------
Литература

Cohn, Mike. 2004. User Stories Applied: For Agile Software Development. Boston, MA: Addison-Wesley.
Martin, Robert. 2009. Clean Code: A Handbook of Agile Software Craftsmanship. Boston: MA: Pearson Education.
Poppendieck, Mary, and Tom Poppendieck. 2007. Implementing Lean Software Development: From Concept to Cash. Boston, MA: Addison-Wesley.
Jeffries, Ron. 2001, August. “Essential XP: Card, Conversation, and Confirmation.” XP Magazine.

---------------------------

7. Bill Wake. www.XP123.com.

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

9. Там же

10. Источник: [Poppendieck 2007].

У Вас Agile? Проверим?..

Автор: Александр Якима (www.enter-agile.com)

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

Вопрос №1: У вас итерационная разработка? Иными словами, работает ли ваша команда четкими короткими (одно-, двух- или нескольконедельными) таймбоксами?

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

Вопрос №2: Является ли основной целью и результатом каждой итерации работающая версия продукта?

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

Вопрос №3: Является ли для команды принятие/непринятие итерации продакт оунером существенным и действенным показателем успешности их работы?

Если команда просто работает, даже итерационно, но команда не ставит перед собой постоянной целью получение фидбека от продакт оунера (да или нет; принята итерация или нет...) - это не Agile. Очень важно понимать, что в этом пункте не может быть исключений, например: "а у нас заказчик такой... - ему все равно". Иногда выходом является проксирование функции продакт оунера менеджером продукта, есть и другие варианты. Однако суть такова - без авторитетной приемочной роли п/о это работа на холостых оборотах, а не Agile.

Вопрос №4: Сдает ли ваша команда релиз всегда вовремя и качественно?

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

Вопрос №5: Знает ли и понимает ли ваша команда в каждый момент времени цели продукта в целом, текущего релиза в частности и, наконец, итерации?

Если нет, то эффективная доставка бизнес-ценности конечному пользователю нарушена в корне.

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

Основы пользовательских историй. Часть 2: Форма

Дин Лэффингуэл (Dean Leffingwell, blog), Пит Беренс (Pete Behrence)

Перевод: Александр Якима (www.enter-agile.com)


Карточка, диалог и подтверждение


Рон Джеффрис (Ron Jeffries), другой среди создателей XP, дал описание, ставшее для нас наиболее предпочтительным представлением о пользовательских историях. Он воспользовался словосочетанием: Карточка, Диалог и Подтверждение [4], для описания трех элементов стори, где:

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

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

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

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

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


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

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

Как <роль> я могу <действие>, так что <бизнес-ценность>

где:

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

Мы называем эту конструкцию [5] “голосом пользователя” и находим ее крайне полезной, поскольку она охватывает проблемную область (доставляемую <бизнес ценность>) и область решения (<действие>, производимое пользователем с помощью системы). Она также выдвигает пользователя (<роль>) на приоритетное место для команды, фокусируя таким образом команду на бизнес ценностях и решении настоящих проблем для настоящих людей.

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

Например, пользователь бытовой системы управления энергопотреблением желал бы следующего [6]:


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


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


Детали пользовательских историй

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


Критерий принятия стори


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

Например,


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


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

ПРОДОЛЖЕНИЕ СЛЕДУЕТ...

--------------------------------------------
4. http://xprogramming.com/xpmag/expcardconversationconfirmation/

5. В поисках происхождения этой конструкции я получил комментарий от Майка Кона (Mike Cohn): “Я начинал работу с командой в компании Connextra в Лондоне и это было упомянуто на XP2003. Я стал использовать это и в дальнейшем и написал об это м в моей книге, изданной в 2004 году, User Stories Applied.”

6. Автор приносит благодарность Дженнифер Фосетт (Jennifer Fawcett), сотруднику компании Tendril Networks, за предоставление примеров
Powered by Blogger