Попробуйте разбивать большие истории, разделяя функциональные и нефункциональные аспекты на отдельные истории.
Например, этот подход можно применить, если новая функция должна занимать менее установленного объема памяти, выстраивать линию, имеющую меньше определенного числа форм, или занимать критические ресурсы менее определенного количества времени.
Разбивка историй со смешанным приоритетом
В некоторых случаях одна история содержит несколько более мелких субисторий с различной приоритетностью. Допустим, проект включает в себя типичную историю, связанную с регистрацией: «Как пользователь я должен зарегистрироваться, чтобы войти в систему». Владелец продукта обозначает свои условия удовлетворенности для этой истории, которые включают в себя следующее:
• Если пользователь вводит корректные имя и пароль, он получает доступ.
• Если пользователь вводит некорректный пароль три раза подряд, он лишается доступа до тех пор, пока не свяжется со службой поддержки клиентов.
• Если пользователю отказали в доступе, на его адрес направляется электронное письмо о том, что была совершена попытка использовать его учетные данные для получения доступа.
Эта история слишком велика для реализации в одну итерацию, поэтому ее необходимо разбить. Разбивку можно осуществить путем выявления низкоприоритетных элементов. В нашем случае владелец продукта не может отгрузить продукт, если он не поддерживает ключевую функциональность, связанную с регистрацией. Он может, однако, выпустить продукт без механизма ограничения времени на повторный ввод данных или без отправки электронного письма о попытке получения доступа. Это позволяет нам сформулировать еще одно правило разбивки историй:
Разбивайте большую историю на более мелкие, если маленькие истории имеют разные приоритеты.
Не разбивайте историю на задачи
Иногда попадаются функции, которые сложно разделить. В таких ситуациях возникает соблазн разбить их на составляющие задачи. Для большинства разработчиков программного обеспечения анализ функции и разбивка ее на составляющие задачи настолько привычны, что выполняются практически автоматически. Вместе с тем избегайте разбивки истории следующим образом:
• Программирование пользовательского интерфейса.
• Написание среднего яруса.
Избежать этого соблазна лучше всего помогает рекомендация Ханта и Томаса (Hunt and Thomas, 1999) применить к системе так называемый подход «трейсер буллет» (tracer bullet). Трейсер буллет затрагивает все слои функции. Это может означать поставку частично реализованного пользовательского интерфейса, среднего яруса и базы данных. Поставка связного подмножества всех слоев функции почти всегда лучше поставки одного полного слоя. Это дает нам следующее правило:
Не разбивайте большую историю на задачи. Вместо этого постарайтесь применить ко всей истории подход «трейсер буллет».
Избегайте соблазна добавить взаимосвязанные изменения
После разбивки истории и доведения ее до подходящего размера не усугубляйте ситуацию, добавляя работу в историю. Нередко возникает соблазн добавить так называемые взаимосвязанные изменения. Мы говорим себе: «Раз уж я работаю с этой программой, почему бы не внести в нее другие давно напрашивающиеся изменения». Под ними может подразумеваться исправление обнаруженных ошибок или решение какой-либо старой проблемы попутно с работой над отдельной задачей в этой же части программы. Вместе с тем приоритетность таких действий должна определяться точно так же, как приоритетность других функций. Другими словами, что имеет более высокий приоритет — растянувшееся на полдня устранение ошибки годичной давности или затрата такого же количества времени на что-нибудь другое? Ответ, понятно, полностью зависит от контекста. Таким образом, мы получаем последнее правило этой главы:
Избегайте ухудшения ситуации в результате добавления взаимосвязанных изменений к соответствующим образом оцененной функции за исключением случаев, когда эти взаимосвязанные изменения имеют такой же приоритет.
После всех этих рекомендаций по разбивке историй может показаться, что все пользовательские истории, с которыми предстоит работать, должны быть как можно меньше. Это не так. Для команд, работающих двухнедельными итерациями, приемлема разбивка историй на такие части, на реализацию которых требуется примерно от двух до пяти дней. (Истории можно по-прежнему оценивать в пунктах, однако к тому моменту, когда команда доберется до разбивки, она уже будет знать, сколько пунктов или идеальных дней эквивалентно сроку два — пять дней.) Истории должны быть немного меньше однонедельной итерации и могут быть, но необязательно, немного крупнее для более продолжительных итераций. Истории с такими приблизительными размерами лучше всего укладываются в короткие итерации agile-проектов.
Читать дальше
Конец ознакомительного отрывка
Купить книгу