2007/04/04

Об agile по-русски: User Stories, часть 1

«Разработка ПО - это игра изобретательности и кооперации»
Элистер Коуберн (1)


О чем эта статья?

Это одна из статей серии «Про agile по-русски» (см. сноску внизу про значение термина «agile»), идея которых поделиться опытом использования agile принципов (2) в разработке программного обеспечения. Основная суть этих подходов – кооперация между всеми членами проекта и адаптивность процесса разработки к неизбежным изменениям. Также важным аспектом Agile является принятие человеческого фактора в проекте как неотъемлемой части и более того – как наиважнейшей причиной прогресса. Agile акцентирует важность поддержания человеческих отношений и учета человеческих особенностей для успеха проекта.

Эта статья рассказывает о применении «user stories» («пользовательских историй») - одной из практик agile. Далее для краткости я буду называть их просто «историями».

Для кого эта статья?

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


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

Как структурирован этот материал?

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


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


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


Email: alexey@krivitsky.com

Как я познакомился с User Stories

Скажу честно, пока я не прочел книги Майка Кона (3), я не верил в то, что этот подход жизнеспособен. Я читал книги по экстремальному программированию (4), про то, как заказчики высказывают требования в виде коротких фраз и обсуждают их с командой, - но все это было далеко от моего понимания, в прочем, как и другие особенности XP... И мне кажется, я был не одинок.


К тому моменту, когда мне попались книги Майка, мой проект уже работал по Scrum (5), и я, видимо, уже созрел для восприятия более «крутых» тем из agile. Одной из таких тем для меня стали пользовательские истории.

User stories: экстремальный подход

Как и все другие идеи из agile, идея историй (если отбросить все предубеждения) весьма прозрачна и логична, как говорят: «its about common sense» (5).


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

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


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


Почему же обсуждение требований так важно?

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

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

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

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


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


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


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

Как это работает на практике? Пример написания историй

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


Это короткое предложение – ничто иное как видение (vision) системы. Его вполне достаточно для того, чтобы начать описывать истории. Но сначала, давайте идентифицируем группы пользователей – истории будут рассказаны от их имени. Знание о будущих пользователях поможет нам сфокусироваться на нуждах каждого из них, не упустив важные моменты в требованиях к системе. И так, разными аспектами системы будут пользоваться такие обобщенные пользовательские роли:


  • Те, которые хранят и обмениваются своими фотографиями – назовем их «пользователи».

  • Те, кто размещают свою рекламу, ориентированную на «пользователей» системы – назовем эту группу «рекламодатели».

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


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


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


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


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


Итак, истории:


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


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


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


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


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


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


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


6 Как пользователь я могу удалить свою учетную запись и перестать быть пользователем системы.


Обсуждая концепцию учетных записей, рождаются также следующие истории:


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


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


Просто? Достаточно. По крайней мере, не сложнее, чем писать спецификации. Но дальше - интереснее.

Вопросы?

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

Куда делись детали?

Первый вопрос, который задает человек, который привык работать с более тяжеловесным подходом к требованиями (основанным к примеру на подходе Software Requirements Specifications из RUP), это «куда подевались детали?»


Это вопрос затрагивает ключевой аспект использования историй. Попробую коротко объяснить.


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


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

Пример детализации.

Рассмотрим одну из историй, идентифицированную выше:


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


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


К истории дописывается этой комментарий. Теперь история выглядит так:


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

Нужен проверенный email и выбранные пользователем имя и пароль.


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


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

Нужен проверенный email и выбранные пользователем имя и пароль.

Тест 1: пользователь не может ввести пароль меньше 6 символов

Тест 2: пользователь не может ввести имя меньше 3 и больше 20 символов

Тест 3: пользователь должен иметь уникальное имя в системе

Тест 4: после регистрации пользователь должен получить имейл для активизации своей учетной записи

Тест 5: пользователь не может войти в систему, если учетная запись не была активизирована

Тест 6: при успешном входе система приветствует пользователя текстом «Добро пожаловать, <имя пользователя>»


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


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

Мощные инструменты работы с историями: упорядочивание, разбиение и группировка

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


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


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


Вот пример, как могли бы быть отсортированы истории вышеописанного проекта (это всего лишь один из вариантов, конечно, есть и другие):


4 Как гость я могу зарегистрироваться в системе для получения пользовательской учётной записи и последующей работы.


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


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


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


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


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


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


6 Как пользователь я могу удалить свою учетную запись и перестать быть пользователем системы.


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


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


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


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


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


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


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


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


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


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


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


Как вы до сих пор справлялись с подобными задачами?

Динамика знаний

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


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


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

Что дальше?

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


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


Буду рад комментариям.

Сноски

«Agile»

Возможные переводы: «гибкие», «динамичные», «адаптивные», во избежание искажения смысла я буду использовать оригинальный термин. Смотрите другую статью из этой серии статей на тему о сложности перевода этого термина - http://www.krivitsky.com/2007/02/blog-post.html


«Заказчик»

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

Ссылки

(1) Alistair Cockburn http://alistair.cockburn.us/index.php/Software_development_as_a_cooperative_game

(2) Agile principles - http://agilemanifesto.org/principles.html

(3) Mike Cohn - http://www.mountaingoatsoftware.com/books

(4) XP - Extreme Programming Explained: Embrace Change by Kent Beck

(5) Scrum. It’s about common sense - http://controlchaos.com/


Алексей Кривицкий,
Редакция от 7.04.2007