Использование storyotype-ов для деления раздутых XP историй
June 7, 2012 | Posted by admin under Практики, Статьи |
Автор: Gerard Meszaros
http://storyotypespaper.gerardmeszaros.com/
Резюме. Идеальный XP проект состоит из определенных заказчиком историй, правильного размера, ориентированных на менеджмент в соответствии с XP принципами и практиками. Слишком большая история создает множество проблем: она может не влезть в одну итерацию; очень много задач нужно скоординировать; она может быть слишком большой для адекватного тестирования на функциональном уровне; слишком много несущественной функциональности отправленной в разработку на ранней стадии может привести к тому, что отложится реализация существенной. Для команд недавно пришедших в XP управление размером историй становится особенно сложным, из-за нехватки опыта, требуемого для упрощения и деления больших историй. Этот отчет рассказывает о четырех эвристиках (storyotype-ах), которые мы использовали в наших XP проектах для успешного управления размером историй.
Введение
В ClearStream Consulting мы помогли многим клиентам узнать, как применять eXtreme Programming (XP) в их проектах. Общая проблема, с которой они сталкивались, – это получение историй нужно гранулярности; большинство проектов начинались с “раздутых историй”, которые нужно было поделить на более мелкие. Для команд с опытом использования “use case-ов” это было особенно трудно, потому что use case-ы могут иметь много сценариев. Эти сценарии могут существенно различаться по бизнес ценности, и их не нужно включать в одну “use case историю”. Чтобы помочь этим клиентам понять, как структурировать их истории, мы создали набор из четырех “storyotype-ов”. Мы попросили их определить, какие storyotype-ы имеет каждый кандидат на историю, и если их у него больше одного, мы заставляли их обсуждать цену деления этой истории на более мелкие, в идеале по одной на каждый storyotype. Цель данной статьи – поделиться нашим опытом управления размером историй в XP проектах. Начнем с описания проблем, возникающих при управлении размером историй. Затем описываются четыре storyotype-а, встречающиеся в проектах информационных систем, и то, как их использовать для борьбы с этими проблемами.
Проблема с историями
Чтобы понять проблемы с гранулярностью историй, поможет краткое описание концепции истории в XP. Впервые они были описаны в [1] и [2]. Заказчик отвечает за определение функциональности системы в виде коротких “историй” из одного или двух предложений. Каждая история должна описывать функциональность, которая имеет реальную бизнес ценность для заказчика. С точки зрения планирования история – это единица приоритезирования, составления расписаний и измерения прогресса, который заказчик может увидеть. Для XP проекта характерны маленькие частые релизы, каждый из которых состоит из ограниченных по времени итераций. В релиз входит одна или несколько историй, что определяется, базируясь на приоритете и размере истории. История должна быть завершена в течение релиза, на который она запланирована, иначе заказчику не будет поставлена ценность. Большая история создает проблемы в трех областях: Планирование релиза, Координирование задач и Тестирование историй.
Планирование релиза
Первая проблема, которую большие истории создают для XP команд – это планирование релиза. Чем крупнее истории, тем меньше их влезет в релиз. (Большие истории также сложнее оценивать.) Это дает заказчику меньше гибкости в выборе того, что должно быть сделано. Слишком много функциональности, связанной в одну историю, заставляет убирать из ранних релизов другую, не менее важную, функциональность, что приводит к ненужному откладыванию значимых демо. Если истории остаются слишком большими на протяжении всего проекта, то может быть отложена реализация существенной ключевой функциональности, из-за того что раздутые истории содержали несущественную функциональность, и ее разработка заняла все ресурсы.
Координирование задач
Координирование задач – это вторая область, в которой возникают проблемы. Большая история создает большое число задач или большие задачи. Интегрирование этих задач может быть проблематичным.
Обычно наши XP проекты не требуют микроменеджмента задач. Не нужно прорабатывать детальную группировку и зависимости задач, до тех пор пока истории достаточно маленькие. С более крупными историями появляются дополнительные накладные расходы на организацию последовательности связанных задач, чтобы убедиться что команда продвигается в направлении общей подцели в каждый момент времени в течении итерации.
Тестирование историй
Третья проблема – слишком большая гранулярность тестирования. Заказчик отвечает за определение и подписание тестов. Если история становится большой, требуется больше тестов, чтобы проверить всю функциональность. Заказчику сложно сразу провести все эти тесты. Оказалось, что завершаемость пользовательского тестирования падает, если число тестов, необходимых для истории превышает 10. Меньшие истории, как правило, более полно протестированы, чем крупные.
Использование storyotype-ов для разбиения историй
Разбиение историй описано в [1] и [2] как один из основных методов управления объемом в XP проектах. История должна отвечать следующим критериям:
- Каждая история должна описывать функциональность , которая представляет реальную бизнес ценность для заказчика.
- Истории не должны иметь ценность, если они в дальнейшем делятся.
- Функциональность, описанная в одной истории, должна иметь одну и ту же важность для заказчика. Т.е., относительный приоритет должен быть тем же.
- Функциональность должна иметь один уровень определенности. Т.е., если какая-то функциональность абсолютно ясна, а какую-то нужно обсуждать с бизнесом детально, то должны быть по крайней мере две разные истории, потому что одна готова к реализации, а другая нет.
Дальнейшие указания предназначены для “начальной истории” (первой построенной истории; особый случай каждого проекта) в [3].
Эти указания помогут новичкам в XP, но они не помогут им понять, как сделать историю правильного размера. У тех, кто пришел из мира use case-ов, есть тенденция к описанию функциональности в форме use case-ов, в качестве основы для историй. Но use case-ы – это неверная гранулярность для историй. Они слишком большие и слишком маленькие в одно и то же время.
Use Case-ы слишком маленькие. Многие use case-ы не могут быть протестированы независимо от другой функциональности. Их можно выполнить независимо, но результаты можно проверить только используя другой use case, чтобы проверить состояние системы. Или use case может зависеть от другого use case-а, чтобы задать состояние системы перед его выполнением.
Use Cases-ы слишком большие. Есть много определений того, из чего же должен состоять use case, но большинство определений согласуются в том, что он включает все возможные пути , в которых пользователь может достичь какой-то цели или получить какой-то результат. Обычно у use case-а есть несколько или много сценариев. Некоторые из сценариев используются очень часто (сценарий “счастливого пути” и несколько других), а другие могут быть патологическими случаями , которые происходят так редко, что не стоит их автоматизировать. Т.е. они дают недостаточную “бизнес ценность”,чтобы оправдать их реализацию с помощью ПО.
Сценарии использования – это хорошо, но не достаточно. Use case-ы обычно состоят из нескольких или многих сценариев ( “альтернативные пути” в use case-е), которые описывают, как работают use case-ы на разных предварительных состояниях системы. Каждый сценарий – это кандидат на историю, поэтому его можно приоритезировать независимо от других сценариев. Часто для решения проблемы “use case-ы слишком маленькие” их нужно скомбинировать со сценариями других use case-ов, чтобы получить правильно тестируемую историю. Но даже сценарии могут быть слишком большими для одного релиза.
Четыре Storyotype-а
Чтобы облегчить командам, новичкам в XP, прийти к правильной гранулярности историй, мы выделили следующие четыре “storyotype-а” (сокращение от “story stereotypes” – стереотипы историй.) Эти storyotype-ы используются, чтобы охарактеризовать каждую историю и дать средство для разбивки “раздутой истории” на более мелкие, но все еще имеющие ценность куски. Хотя следующие описания storyotype-ов часто ссылаются на use case-ы, storyotype-ы можно применять к любой истории, независимо от того, похожа ли она на use case или это более крупная XP история. Просто use case-ы – чаще всего встречающаяся форма описания требований, поэтому на них удобно ссылаться в описаниях storyotype-ов.
Storyotype: Новая функциональность
Этот storyotype описывает новую функциональность, которая независима от функциональности, описанной в предыдущих историях. В мире use case-ов эти истории могут быть охарактеризованы как «счастливый путь» одного use case-а или нескольких взаимосвязанных use case-ов. Для случая нескольких use case-ов – они должны быть созависимы (как яйца и цыплята): трудно было бы протестировать один без другого. Общий пример – это CRUD (Create – создать, Read-прочитать, Update-изменить и Delete-удалить) для бизнес сущности; очень трудно изменить сущность, которая еще не создана, и очень трудно проверить, что изменение прошло успешно, если нет возможности прочитать сущность. Поэтому операции «создать, изменить и прочитать» для бизнес сущности можно сгруппировать в одну историю с “основной функциональностью”. Use case функциональность, включенная в эту историю, должна быть ограничена одним сценарием, без обработки условий. Другие storyotype-ы описывают дополнительную функциональность, относящуюся к (расширения) этой основной новой функциональности. Если пользовательский интерфейс требуется как часть истории, то это должен быть“простейший UI, который работает ”. Т.е. это основные окна, поля, кнопки или пункты меню, требуемые для обеспечения функциональности. Все остальное, связанное с UI, принадлежит storyotype-у Улучшение UI.
Storyotype: Вариация существующей функциональности
Истории с этим storyotype-ом описывают вариацию функциональности, представленной в другой истории (чаще всего это история со storyotype-ом Новая функциональность.) Это может включать одно или более расширений или исключений (как описано в [4]). Это тип истории, который представляет условную логику в ПО, т.к. каждая из этих вариаций обычно требует проверки какого-то условия и выполнения другого пути, когда условие верно. Когда история-Вариация вовлекает несколько use case-ов, то обычно это те же use case-ы, которые описывают историю- Новая функциональность, которую расширяет история-Вариация. UI, относящийся к этому storyotype-у, должен быть ограничен добавлением полей, требуемых для ввода или просмотра данных для принятия решений.
Storyotype: Новое бизнес правило
Истории Новое бизнес правило (часто называемые “валидация ввода” или “проверка редактирования”) расширяют истории Новая функциональность и Вариация, добавляя дополнительные ограничения, которые должно поддерживать ПО. Этот тип истории добавляет условную логику в ПО в виде ограничений или допущений, т.к. обычно нужна проверка некоторого условия и если она срабатывает, то требуется сообщение об ошибке. UI по этому storyotype-у ограничивается сообщением пользователю об ошибке и средствами по устранению проблемы.
Storyotype: Улучшение UI
Дизайн и разработка UI это сложный предмет, который быстро может стать основным “поглотителем времени”, если не управлять им. И это одна из областей, наиболее подходящих для согласования объема проекта с доступными ресурсами. Поэтому действительно стоит отделять истории, относящиеся к разработке сложных пользовательских интерфейсов, от тех, что относятся к бизнес функциональности. Истории с этим storyotype-ом направлены на улучшение UI и не должны включать бизнес функциональность. Если есть несколько “измерений” для улучшения интерфейса (например, drag&drop, списки с возможностью выбора нескольких пунктов, распознавание голоса), то для каждого должна быть своя история или истории, чтобы заказчик мог выбрать функциональность, которая ему больше нужна, и не тащить вместе с этим менее важную (для него) функциональность.
Рефакторинг историй на основе storyotype-ов
Определив storyotype-ы для каждой истории, мы можем принять сознательное решение о делении на истории с единственным storyotype-ом или о том, чтобы оставить много storyotype-ов в некоторых историях. Когда есть много (маленьких) историй, возникают дополнительные накладные расходы. Комбинирование в более крупные, дает меньше историй для оценки и облегчает их отслеживание.
Мы редко видели пользу в том, чтобы комбинировать истории с разными storyotype-ами. Основное исключение – это когда истории с одним storyotype-ом слишком малы для задачи разработки. Это часто бывает на фазе исправления ошибок и добавления минорных улучшений.
Мы видим пользу в комбинировании двух историй с одним storyotype-ом (например, две истории Бизнес правила) , поскольку это может быть неважно, называем мы это одной историей или несколькими. Опять же, размер историй – это ключевой параметр выбора: мы не хотим, чтобы полученная история была слишком большой для одной итерации, и мы не хотим заставлять заказчика “платить за” работу, которая ему может быть и не нужна, только потому, что она попала в одну историю вместе с другой функциональностью.
Управление историями Улучшение UI
Стиль пользовательского интерфейса затрагивает разные части функциональности системы. Изменения в стиле UI может повлечь пересмотр многих частей системы. Основная проблема с разработкой историй Улучшение UI – это то, чтобы обойтись без излишнего пересмотра всех частей UI, в попытках построить UI c высокой юзабильностью. Может потребоваться несколько (например, 3 или 4) попыток, чтобы найти метафору UI, которой были бы довольны пользователи. Без внимательного управления процессом нам возможно придется применять историю Улучшение UI к каждой части пользовательского интерфейса приложения, пока мы не узнаем, чего же действительно хочет заказчик.
Наиболее эффективной стратегией мы считаем построение системы с простым UI в начале, и выполнение нескольких историй Улучшение UI, предназначенных для определенной части системы. Это дает возможность получить отклик на UI технологию и стиль , не делая крупных вложений в UI для всей системы. Как только пользователи становятся довольны UI в пилотной части системы, ту же UI парадигму можно применять к остальной системе (обычно в поздних итерациях или релизах). Это может значительно уменьшить работы с UI кодом. (Это одна из областей, где действительно стоит избегать переделывания, используя Опционное мышление, Options Thinking [5] , чтобы отложить работы до принятия решения о значительном влиянии.)
Предупреждение насчет комбинирования историй
Независимо от storyotype-ов, мы считаем, что стоит объединять две или несколько историй, когда у них идентичная бизнес ценность и один уровень спецификации. Мы также хотим быть уверены, что ценность/определенность не изменятся до того, как мы их построим. Это прекрасный аргумент для “раннего деления и позднего объединения ”!
Пример
Рассмотрим приложение, которое готовит счета для разных заказчиков сервиса. Чтобы показать применимость storyotype-ов независимо от подхода, используемого для историй, мы дадим описание функциональности в виде use case-ов и раздутых историй. Это делается не для того, чтобы показать, как перейти от use case-а к раздутой истории, а для того, чтобы показать, что любой из этих вариантов может быть начальной точкой для рефакторинга.
Пример с use case-ами
В систему включены следующие use case-ы: Вести заказчиков, Вести цикл счетов, Генерировать счета и Отправлять счета. Use case-ы Вести XXX включают возможность создавать, изменять и либо удалять либо делать устаревшими соответствующую бизнес сущность, там где это имеет смысл.
Use case “Генерировать счета” используется для создания счетов, которые затем можно просмотреть, перегенерировать, завершить и отослать. Счета могут содержать расходы, основанные на простой подписке (месячные платежи, например), использовании (например, из расчета за единицу) и введенные вручную платежи (особые случаи). Он может быть использован для генерации счетов для всех заказчиков или только для избранных заказчиков.
Пользователи хотят иметь возможность выбирать заказчика с помощью списка множественного выбора, нажимая на кнопку для добавления заказчика в список генерируемых счетов или перетаскивая заказчиков в список генерируемых счетов. Пользователи также хотят, чтобы система запоминала последнюю использованную группу заказчиков. И система не должна позволять генерацию счета для заказчика, который еще не утвержден менеджером по продажам.
Use case “Просмотреть счет” позволяет пользователю увидеть список доступных счетов и выбрать один из них для более детального просмотра.
Use case “Завершить счет” используется чтобы “заблокировать” счет, так что его нельзя перегенерировать. Счет нельзя отослать заказчику, пока он не завершен.
Пример с раздутыми историями
Команда, не знакомая с use case-ами может сделать следующие истории для той же функциональности.
История 1: Генерация счета: Сгенерировать счет, состоящий из одного расхода по подписке для одного или всех заказчиков. Просмотреть результирующий счет. Пользователь может выбрать заказчиков, чьи счета надо сгенерировать, используя список множественного выбора или используя кнопки Добавить/Удалить для перемещения заказчиков из панели Все заказчики на панель Выбранные заказчики. Система должна помнить последний набор заказчиков, для которых был сгенерирован счет. Счет не может быть сгенерирован для заказчика, пока менеджер продаж не утвердил его. Счет не может быть сгенерирован для заказчика , пока не будут предоставлены все обязательные данные. Это включает имя, контактную информацию (почтовый адрес, номер телефона), звание и имя компании. Для создания заказчика достаточно имени, но им нельзя посылать счета.
История 2: Послать счет заказчику: Когда пользователь удовлетворен созданным счетом, он может завершить его и послать заказчику. Как только счет завершен его уже нельзя перегенерировать или изменить.
История 3: Расходы, основанные на использовании: Создать счет, который включает расходы, основанные на использовании. Данные по использованию читаются из плоского файла, а тариф за использование можно установить через UI. Сгенерировать счет и просмотреть его, чтобы проверить, что тарифы применены корректно. Присмотреть результирующий счет.
Характеристика раздутых историй с помощью storyotype-ов
Рассмотрим историю, которая описывает процесс генерации счета. Этот “use case story” включает много storyotype-ов:
Генерация счета для всех заказчиков это пример storyotype-а Новая функциональность. Генерирование счетов для подмножества заказчиков это пример storyotype-а Вариация функциональности.
Поскольку описаны три разные UI метафоры, мы можем предположить, что есть по крайней мере два кандидата для историй Улучшение UI.
Деление истории на основе storyotype-ов
Теперь, когда мы определили storyotype-ы, мы можем провести рефакторинг истории на следующие истории с единственным storyotype-ом:
Новая функциональность: Сгенерировать очень простой счет, состоящий из одного расхода по подписке. Просмотр результирующего счета. Замечание: Это пример “ раздутой истории ”, как описано в [3].
Новая функциональность: Завершить и Послать счет заказчику.
Вариация: Генерация счета, который включает расходы, основанные на использовании. Данные по использованию читаются из плоского файла, за использование берется тариф $1 за единицу использования. Просмотр результирующего счета.
Вариация: Тариф за использование может быть установлен через UI. Сгенерировать счет и просмотреть его, чтобы проверить, что тариф применен корректно.
Вариация: Использовать список с множественным выбором заказчиков, что бы выбрать заказчиков, чьи счета нужно сгенерировать.
Вариация: Запомнить последнее множество заказчиков, для которых генерируются счета.
Улучшение UI: Выбрать заказчиков, для которых генерировать счета (или завершать счет) используя простой двойной список с кнопками добавить/удалить.
Бизнес правило: Счет не может быть послан заказчику до завершения.
Бизнес правило: Завершенный счет не может быть перегенерирован или изменен.
Бизнес правило: Счет не может быть сгенерирован для заказчика , пока менеджер по продажам не одобрит его. Это также требует создание простого UI для утверждения заказчиков (вероятно описанного в use case-е Вести заказчиков.)
Бизнес правило: Нельзя сгененрировать счет для заказчика пока все не будут обеспечены все обязательные элементы данных. Это включает имя, контактную информацию (почтовый адрес, номер телефона), звание, и имя компании. Для создания заказчика достаточно имени, но для него нельзя создавать счета.
Бизнес правило: Только менеджер продаж может утверждать заказчика. Это подразумевает возможность входа в систему, чтобы система определила, кто ее использует. Аутентификация (значит, безопасность) должна быть еще одной историей.
Объединение на основе storyotype-ов
Теперь мы можем принимать сознательные решения насчет того, чтобы каждый экземпляр storyotype-а был в отдельной истории, или чтобы объединить два (или более, но не рекомендуется) storyotype-а в одну историю. В нашем примере мы можем объединить два бизнес правила, относящиеся к генерации счета в одну историю (она все еще будет иметь единственный storyotype). Мы можем назвать эту историю “Бизнес правила генерации счета”. Мы можем решить насчет их объединения, когда мы знаем, что их бизнес ценность и определенность одинаковые и мы уверены, что они не изменятся. Мы можем включить расходы по подписке и за использование в одну историю генерации счета. Мы можем сделать это, зная последовательность выполняемых задач, а не по незнанию.
Заключение
История – это основа для описания, планирования и управления в XP проекте. Правильная гранулярность историй очень важна для эффективного планирования релиза. Четыре storyotype-а, которые мы представили, – это полезный инструмент для понимания размера и сложности историй, независимо от того базируются ли они на use case-ах или раздулись по другим причинам. Они дают командам-новичкам в XP набор эвристик, которые они могут использовать, когда принимают решения о том, как провести рефакторинг историй во время планирования релиза. Эти storyotype-ы появились из нашего опыта использования XP при построении корпоративных информационных систем. Команды, работающие в других проблемных областях, могут посчитать полезным определение storyotype-ов, специфичных для их областей.
Благодарности
Автор благодарит всех коллег из ClearStream, которые поделились своим опытом и пониманием управления историями в различных XP проектах и особенно Ted O’Grady, который вдохновлял меня и давал ценные комментарии на ранних набросках статьи.
Ссылки
1. Beck, Kent. Extreme Programming Explained: Embrace Change, Addison-Wesley, 2000; ISBN 201-61641-6.
2. Beck, Kent. Martin Fowler, Planning Extreme Programming, Addison-Wesley, 2001; ISBN 0-201-71091-9.
3. Andrea, Jennitta. Managing the Bootstrap Story in an XP Project, in Proceedings of XP2001, 2001.
4. Cockburn, Alistair. Writing Effective Use Cases, Addison-Wesley, 2001; ISBN 0-201-70225-8.
5. Poppendieck, Mary and Tom. Lean Software Development, An Agile Toolkit, Addison-Wesley, 2003; ISBN 0-321-15078-3