Основы пользовательских историй. Часть 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].

No comments:

Post a Comment

 
Powered by Blogger