Agile: оценка и планирование проектов

Кон Майк

Часть III

Планирование на основе стоимости

 

 

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

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

 

Глава 9

Приоритизация тем

 

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

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

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

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

• Интеграция с распространенными карманными компьютерами, используемыми в бассейне.

• Импорт и экспорт данных.

• Предоставление официальным представителям возможности следить за результатами заплывов и счетом в соревнованиях.

Каждая из этих тем имеет осязаемую ценность для пользователей программного обеспечения, и им можно присвоить определенную денежную стоимость. С помощью исследований мы можем определить, что поддержка карманных компьютеров предположительно принесет $150 000 в виде новых продаж. Это можно сравнить с ожидаемыми новыми продажами в объеме $200 000, если следующая версия позволит оценивать результаты соревнований по плаванию. Затем можно определить приоритетность этих тем. Однако приоритизация представляет собой нечто большее, чем простой учет денежного дохода от каждого нового набора функций.

 

Факторы приоритизации

 

Определение стоимости темы — дело сложное, и владельцы продукта в agile-проектах нередко дают туманную и по большей части бесполезную рекомендацию «приоритизировать по коммерческой стоимости». Было бы понятно, если бы советовали использовать номинальную стоимость. Но что такое коммерческая стоимость? Чтобы предложить более практичный набор рекомендаций по приоритизации, в этой главе мы рассмотрим четыре фактора, которые необходимо учитывать при расстановке приоритетов разработки новых возможностей:

1. Финансовая стоимость использования функций.

2. Затраты на разработку (и, возможно, поддержку) новых функций.

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

4. Величина риска, ликвидированного в результате разработки функций.

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

 

Стоимость

Первым фактором при приоритизации работы является финансовая стоимость темы. Сколько денег получит или сэкономит организация в результате включения новых функций в тему? Именно это зачастую имеется в виду, когда владельцев продукта просят «определить приоритеты по стоимости для бизнеса».

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

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

 

Затраты

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

Темы нередко кажутся ценными, если смотреть на них только с точки зрения времени реализации. Как это ни банально, очень важно помнить, что время — это деньги. Нередко самым действенным способом добиться этого во время приоритизации является примерный перевод пунктов или идеальных дней в деньги. Предположим, вы повышаете заработную плату всех участвовавших в проекте в течение последних 12 недель и получаете суммарные затраты $150 000. Сюда входят владелец продукта и руководитель проекта, а также все программисты, тестировщики, администраторы баз данных, аналитики, дизайнеры пользовательских интерфейсов и т. д. В течение этих 12 недель команда реализовала 120 пунктов. Тогда можно сказать, что совокупная себестоимость составляет $150 000, а себестоимость пункта — $1250. Допустим, владелец продукта пытается решить, стоит ли включать в следующий релиз функцию размером 30 пунктов. Один из подходов к принятию решения — определить, оправдывает ли новая функция вложения в размере $37 500 (30 × 1250 = 37 500).

В главе 10 «Приоритизация по финансовой отдаче» мы более подробно поговорим о себестоимости и приоритизации на основе финансового вознаграждения относительно затрат.

 

Новые знания

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

• Знания о продукте.

• Знания о проекте.

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

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

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

В проекте, где используется каскадный подход, все неопределенности, связанные с тем, что создается, пытаются устранить до решения проблемы неопределенности того, как это будет создаваться. Именно отсюда проистекает распространенное представление о том, что анализ связан с тем, чтó создается, а дизайн — с тем, как это создается. На рис. 9.1 представлены каскадный подход и agile-подход к устранению неопределенности.

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

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

Я изобразил кривую в правой части рис. 9.1, чтобы показать предпочтительность раннего снижения конечной неопределенности. Почему, спрашивается, я не провел прямую линию или не построил кривую, свидетельствующую о предпочтительности раннего снижения неопределенности средств? Моя линия отражает важность как можно более раннего снижения неопределенности, связанной с тем, каким должен быть продукт. Нет необходимости устранять конечную неопределенность в самом начале (как предполагает традиционный подход), даже при желании это невозможно. Вместе с тем один из самых серьезных рисков в большинстве проектов — это риск создать несоответствующий продукт. Данный риск можно резко снизить через разработку на раннем этапе тех функций, которые быстрее всего позволяют представить или передать работающую программу реальным пользователям.

 

Риск

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

• Риск срыва графика («Мы можем не успеть завершить работу к октябрю»).

• Риск увеличения затрат («Мы можем не найти аппаратные средства с подходящей ценой»).

• Риск функциональности («Мы не обязательно сможем реализовать это»).

Помимо этого, риски можно классифицировать как технологические или деловые.

Классическое противоборство в проекте наблюдается между функциями с высоким риском и функциями с высокой стоимостью. Следует ли проектной команде сначала сконцентрироваться на функциях с высоким риском, которые могут пустить под откос весь проект? Или ей лучше сосредоточить внимание на том, что Том Гилб (Tom Gilb, 1988) назвал «сочными кусками», — на функциях с высокой стоимостью, которые приносят больше всего клиентских долларов?

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

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

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

Затем идут функции с низкой стоимостью и низким риском. Ими занимаются в третью очередь, поскольку они меньше влияют на совокупную стоимость продукта в случае отказа от них и связаны с низким риском.

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

 

Объединение четырех факторов

Чтобы объединить все четыре фактора приоритизации, думайте сначала о стоимости функции по сравнению с затратами, которых эта функция потребует при реализации сегодня. Это позволит определить первоначальный порядок реализации тем. Темами с высоким отношением «стоимость/затраты» следует заниматься в первую очередь.

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

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

 

Примеры

 

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

 

Создание инфраструктуры

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

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

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

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

 

Дизайн пользовательского интерфейса

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

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

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

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

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

 

Резюме

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

1. Финансовая стоимость использования функций.

2. Затраты на разработку (и, возможно, поддержку) новых функций.

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

4. Величина риска, ликвидированного в результате разработки функций.

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

 

Вопросы для обсуждения

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

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

 

Глава 10

Приоритизация по финансовой отдаче

 

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

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

В табл. 10.1 предусмотрена строка для каждого квартала следующих двух лет. Временной горизонт устанавливается по усмотрению команды. Иногда команды предпочитают определять месячную отдачу для одного или двух лет. По моему опыту, для большинства проектов подходит двухлетний период. Это своего рода золотая середина между гаданием относительно отдаленного будущего и разумным взглядом вперед. Из-за высокой неопределенности, связанной с проектами по разработке программного обеспечения, такого подхода придерживаются и другие (Bills, 2004a).

Табл. 10.1 содержит колонки для различных типов отдачи, которые могут быть у тем. Если в вашем проекте фигурируют другие типы отдачи, измените заголовки соответствующим образом. Аналогичным образом используйте другие заголовки колонок, если требуется их конкретизация (например, «Увеличение дохода от клиентов из США» и «Увеличение дохода от клиентов из Европы»). Совершенно не обязательно иметь для всех тем одинаковый набор колонок.

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

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

Нельзя сравнивать проекты и принимать решения о приоритетах, просто суммируя числа в строке «Итого» рабочего листа вроде того, что показан в табл. 10.2, для каждой темы. Поток доходов, который составляет $100 000 в первом квартале, $200 000 во втором и $500 000 в третьем, имеет значительно меньшую ценность, чем такой же поток, в котором доходы изменяются в обратном порядке. Для сравнения множества тем нам необходим один или несколько стандартных финансовых показателей. В этой главе мы рассмотрим следующие показатели:

• Чистая приведенная стоимость.

• Внутренняя ставка доходности.

• Срок окупаемости.

• Дисконтированный срок окупаемости.

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

 

Источники дохода

 

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

 

Новый доход

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

 

Прирост дохода

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

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

• Содержит опциональные модули расширения, которые можно продавать отдельно.

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

• Создает стимулы для использования консультационных услуг (например, по интегрированию с приложением стороннего производителя).

 

Сохраненный доход

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

 

Операционная эффективность

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

Зачастую побудительным мотивом повышения операционной эффективности является ожидаемый рост. Неэффективность, которая может не слишком беспокоить вас сегодня, быстро превращается в проблему, когда компания становится значительно крупнее. Предположим, например, что ваша компания создала веб-сайт по продаже рам для картин. Вы предлагаете на продажу не только огромный набор стандартных рам, но и рамы, изготовленные на заказ. Бизнес развивается хорошо, и компания ожидает значительного роста в течение ближайших двух лет. Точнее, она ожидает десятикратного роста продаж за этот период. Как и в любом бизнесе, определенный процент проданных товаров возвращается компании. Автоматизация учета возвращенного товара никогда не имела высокого приоритета, и в настоящий момент возвратом занимается один человек в течение двух часов в день, включая учет запасов и перечисление средств на кредитную карту покупателя. Два часа, потраченные на этот процесс, могут не представлять проблемы сегодня. Однако с увеличением объема продаж на 1000 % объем возврата, скорее всего, также вырастет на 1000 %, и на его обработку потребуется уже 20 человеко-часов в день. В такой ситуации есть все основания задуматься, не приводит ли этот процесс к неэффективности, которую необходимо устранить.

При поиске возможностей повышения операционной эффективности следует обращать внимание на следующее:

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

• Улучшение интеграции или коммуникации между отделами.

• Снижение текучести кадров.

• Сокращение времени обучения новых сотрудников.

• Любые чувствительные к срокам выполнения процессы.

• Объединение нескольких процессов.

• Все, что повышает точность и уменьшает переделку.

 

Пример: WebPayroll

 

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

В текущий момент мы говорим клиентам, что они должны вводить информацию о заработной плате на наш веб-сайт за три дня до момента выдачи чеков работникам. Наша цель в новой системе — предложение услуги с исполнением на следующий день. Если информация о заработной плате будет введена на сайт WebPayroll до 17:00, то мы сможем сгенерировать чеки, распечатать их и поставить заказчику на следующий рабочий день. Чеки будут вручены клиентам на следующее утро.

Прежде чем начинать оценку дохода от проекта обслуживания на следующий день, необходимо определить, когда он будет реализован. Допустим, разработчики уже оценили истории в этой теме в 150 пунктов. При исторической скорости команды, равной 20 пунктам за двухнедельную итерацию, разработка темы займет 150 / 20 = 7,5 ≈ 8 итераций. Это означает, что повышения дохода и операционной эффективности можно ожидать только после восьмой итерации (если, конечно, нам не удастся поставить частичное решение, что всегда должно быть одной из целей).

 

Определение нового дохода

Предложение обслуживания на следующий день вместо обслуживания через три дня открывает возможности получения нового дохода. Чтобы оценить эти возможности количественно, оценим сначала число новых клиентов, которых мы сможем приобрести. Надежных данных у нас нет. Однако наш торговый представитель Терри говорит, что примерно треть клиентов, с которыми она общается, отказываются от WebPayroll из-за необходимости подавать информацию за три дня. На основе текущих прогнозов по продажам Терри считает, что сможет привлекать в этом году 50 новых клиентов в квартал, а в следующем году — 100 клиентов в квартал. Эти значения включены в колонку «Новые клиенты» табл. 10.3. Хотя функция обслуживания на следующий день появится лишь в середине второго квартала, Терри уверена, что уже в этом квартале привлечет 50 новых клиентов.

Теперь оценим доход на клиента. Это можно сделать, опираясь на данные по существующим клиентам. Нам известно, например, что средний клиент WebPayroll платит нам $400 в год. Однако мы считаем, что услуга с исполнением на следующий день будет наиболее привлекательна для мелких клиентов, тех, которые платят нам в среднем $200 в год. На наш взгляд, можно рассчитывать на дополнительные $100 в год от каждого такого клиента. Совокупная стоимость каждого нового клиента, таким образом, составляет $300 в год, или $75 в квартал. Поскольку обслуживание на следующий день будет доступно на протяжении лишь двух третей второго квартала, доход на клиента в этом квартале пропорционально уменьшается. Эти величины добавляются в колонку «Доход на клиента» в табл. 10.3, которая позволяет определить значения для колонки «Новый доход».

 

Определение прироста дохода

Под приростом дохода понимается дополнительный доход, который мы можем получить от существующих клиентов. На основе наших знаний о существующих клиентах — как часто они опаздывают с подачей информации о заработной плате и т. д., мы считаем, что сможем привлекать примерно по 100 клиентов в квартал до тех пор, пока все 400 существующих клиентов не перейдут на обслуживание на следующий день. Что касается новых клиентов, то услуга будет генерировать примерно по $100 в год, или $25 в квартал после того, как она появится во втором месяце второго квартала. Для расчета совокупного прироста дохода в квартал на основе этих данных сформирована табл. 10.4.

 

Определение сохраненного дохода

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

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

Зная, что каждый существующий клиент приносит $400 в год, т. е. $100 в квартал, мы можем рассчитать сохраненный доход, как показано в табл. 10.5.

 

Определение операционной эффективности

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

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

Бухгалтеры стоят в среднем $20 000 в год. Каждому из них, кроме того, предоставляется место в офисе, определенное оборудование, программное обеспечение и компенсационные выплаты. В сумме эти дополнительные скрытые расходы составляют примерно еще 50 % заработной платы работника. Иными словами, реальная стоимость бухгалтера ближе к $30 000 в год. Это называют полной заработной платой. Количество бухгалтеров, которые не были наняты, и полная заработная плата дают при перемножении операционную эффективность для каждого квартала, как показано в табл. 10.6.

 

Определение затрат на разработку

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

Полная заработная плата в табл. 10.7 рассчитывается путем увеличения заработной платы каждого работника на 50 %. Поскольку итерация занимает две недели, полная заработная плата на итерацию составляет 1/26 величины полной заработной платы. В колонке «Время в проекте» указана доля времени, которая приходится на каждого члена команды в проекте. Все заняты полностью, за исключением одного программиста. В колонке «Скорректированные затраты на итерацию» приведены затраты на проект по каждому участнику с учетом полной заработной платы и времени участия в проекте. В целом затраты команды на итерацию составляют $13 550. Округлим эту величину до $13 500.

Зачастую полезно знать затраты на один пункт (или один идеальный день). Для определения этой величины разделите скорректированные затраты на итерацию на среднюю или ожидаемую скорость команды. Учитывая, что средняя скорость команды WebPayroll составляет 20 пунктов на итерацию, ее стоимость пункта будет равна 13 500 / 20 = 675. Эта информация полезна потому, что, если команду спрашивают, во сколько обойдется разработка элемента, оцениваемого в 100 пунктов, она может сразу дать ответ — $67 500 (100 × 675).

Затраты команды WebPayroll обобщены в табл. 10.8.

 

Сведение всех статей вместе

Результаты анализа затрат, нового дохода, прироста дохода и операционной эффективности сведены вместе в табл. 10.9.

Реализацию функции обслуживания на следующий день предполагается осуществить за восемь итераций, или через 16 недель. На первый квартал приходятся затраты 13 недель в размере $87 750 (13 × 6750). На второй квартал приходятся затраты еще трех недель в размере $20 250.

 

Финансовые показатели

 

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

 

Временнáя стоимость денег

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

Сегодняшнюю стоимость будущих денег мы определяем с точки зрения того, сколько нужно положить в банк сегодня, чтобы получить будущую сумму. Чтобы купить гамбургер стоимостью $5 в следующий вторник, мне необходимо сегодня положить в банк $4,99. Сумму, которую я должен инвестировать сегодня, чтобы получить известную сумму в будущем, называют приведенной стоимостью. Скажем, если я могу заработать 10 % на вложения и хочу получить $1,00 через год, то сегодня мне необходимо вложить $0,91. Другими словами, при ставке 10 % $0,91 — это приведенная стоимость $1,00 через год. Если бы я мог заработать на мои деньги 20 %, то мне сегодня пришлось бы вкладывать только $0,83.

Процесс приведения будущих сумм к их нынешней стоимости называют дисконтированием. Понятно, что процентная ставка, используемая для дисконтирования будущих сумм, критически важна для определения приведенной стоимости. Ставка, по которой организации дисконтируют будущие деньги, называется альтернативными издержками и отражает процентный доход, от которого отказываются, осуществляя данное вложение. У всех нас — физических и юридических лиц — есть разные возможности инвестирования денег. Я могу разместить деньги на сберегательном счете в банке или вложить в акции, инвестировать их в недвижимость или положить под матрас. Организации могут инвестировать деньги аналогичным образом или вкладывать их в проекты. Если в прошлых проектах организация обычно зарабатывала 20 %, то новые проекты оценивают по такой же ставке — 20 %. Альтернативные издержки организации составляют 20 %, поскольку вложение средств в новый проект означает, что организация отказывается от возможности инвестировать их в какой-либо другой проект, который принесет 20 %.

 

Чистая приведенная стоимость

Первым показателем, который мы рассмотрим в целях оценки темы, является чистая приведенная стоимость (net present value — NPV). Для определения NPV суммируют приведенные стоимости каждой статьи в потоке будущих стоимостей. Для этого используется следующая формула:

где i — процентная ставка, а Ft — чистый денежный поток периода t.

Чтобы понять, как это работает, вернемся к нашему примеру WebPayroll. Как уже говорилось, ожидаемые затраты на проект обслуживания на следующий день составляют $108 000, а генерируемые в результате его реализации доходы и экономия обобщены в табл. 10.9 и воспроизводятся в колонке «Чистый денежный поток» табл. 10.10. Колонка «Коэффициент дисконтирования» в этой таблице представляет собой множитель (1 + i)—t из формулы для расчета NPV и отражает величину, на которую будет дисконтироваться будущий денежный поток. Последняя колонка «Приведенная стоимость» — это произведение чистого денежного потока и коэффициента дисконтирования. Она, например, показывает, что приведенная стоимость $18 250 в конце третьего квартала года составляет $16 701. Сумма значений в колонке «Приведенная стоимость» дает совокупную NPV, равную в нашем случае $46 341.

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

 

Внутренняя ставка доходности

Внутренняя ставка доходности (internal rate of return — IRR), которую иногда называют рентабельностью инвестиции (return on investment — ROI), позволяет представить доход от проекта в процентном выражении. Если NPV показывает, сколько денег можно получить от проекта (в сегодняшней, приведенной стоимости), то IRR говорит о том, как быстро растут деньги, вложенные в проект. IRR облегчает сравнение проектов, как это видно из табл. 10.11. Какой проект вы бы выбрали?

Большинство, надо думать, предпочтут получать 43 % на свои вложения, несмотря на то, что у проекта А выше NPV (он к тому же требует более высоких первоначальных вложений). Денежные потоки для этих двух проектов представлены в табл. 10.12.

Многие организации определяют минимально привлекательный уровень доходности (minimum attractive rate of return — MARR). Финансируются только те проекты или темы, у которых IRR превышает MARR. Для NPV такой порог устанавливать нецелесообразно, поскольку значения NPV сильно зависят от масштаба проекта. В случае введения порогового значения для NPV небольшие (но ценные) проекты никогда не получат одобрения.

IRR определяется как процентная ставка, при которой NPV денежного потока равна нулю. Другими словами, это значение i*, при котором

Формула для расчета IRR сложная, и ее рассмотрение выходит за рамки настоящей книги. К счастью, большинство электронных таблиц содержат удобную для использования функцию определения IRR. Если вы хотите рассчитать IRR вручную, обратитесь к работе Стива Токи (Steve Tockey, 2004), который, пожалуй, лучше других объясняет, как это сделать. Вместе с тем даже при использовании электронных таблиц необходимо помнить о нескольких важных предварительных условиях:

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

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

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

Поскольку денежный поток темы обслуживания на следующий день на сайте WebPayroll удовлетворяет этим условиям, мы можем рассчитать IRR. Чтобы сделать это в Excel, введите в ячейку такую формулу:

+IRR({0, –85750, –14150, 18250, 20750, 29000, 36500, 36500}).

Числа в фигурных скобках — это денежные потоки для каждого из восьми кварталов. Ноль в начале показывает, что предварительные затраты в первый день проекта отсутствуют (они вполне могут и присутствовать, если WebPayroll купит дополнительные серверы для осуществления проекта). Для проекта обслуживания на следующий день на WebPayroll IRR составляет 12 %, т. е. ожидаемый денежный поток эквивалентен получению годового дохода на вложения компании в размере 12 %.

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

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

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

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

 

Срок окупаемости

С помощью NPV мы можем представить денежный поток в виде одного показателя — приведенной стоимости. Альтернативно денежный поток можно представить в виде процентной ставки — IRR. Третьим вариантом представления денежного потока является время, необходимое для возврата первоначальной инвестиции. Этот показатель называют сроком окупаемости. Чтобы понять, как его определяют, в табл. 10.13 приведены расчеты срока окупаемости для проекта обслуживания на следующий день WebPayroll.

В первом квартале WebPayroll вкладывает в проект $85 750. Во втором квартале компания делает дополнительное вложение в размере $14 150. В третьем квартале она начинает возвращать вложенные средства и получает $18 250. В какой-то момент в седьмом квартале чистые вложения становятся положительными, поэтому говорят, что срок окупаемости проекта составляет семь кварталов.

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

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

 

Дисконтированный срок окупаемости

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

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

 

Сравнение отдачи

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

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

Дополнительная информация по экономике проектов

Хотя в этой главе изложены базовые аспекты использования и расчета четырех финансовых показателей, многое осталось нераскрытым. Дополнительную информацию по вопросу экономики софтверных проектов можно почерпнуть в книге Стива Токи «Рентабельность разработки программного обеспечения: Максимизация доходности инвестиций» (Return on Software: Maximizing the Return on Your Software Investment) (Steve Tocke, 2004). Все четыре финансовых показателя в данной главе и формулы для их расчета позаимствованы из этой книги.

 

Резюме

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

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

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

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

 

Вопросы для обсуждения

1. Если бы вашей организации пришлось выбирать темы, перечисленные в табл. 10.15, каким было бы наиболее приемлемое решение? Почему?

2. Как бы вы смоделировали доход для темы в своем текущем проекте? Подходят ли вам предложенные категории нового дохода, прироста дохода, сохраненного дохода и операционной эффективности? Какие категории вы бы использовали вместо названных?

 

Глава 11

Приоритизация по желательности

 

Эти строки я написал в гостиничном номере. Там было довольно чисто, имелся душ, стояли кровать и письменный стол. Каждый из этих атрибутов является базовым, и я ожидаю увидеть их в любом гостиничном номере. Если что-то отсутствует, я просто не остановлюсь в такой гостинице. В той гостинице кровать была более удобной, чем в большинстве других; кроме того, гостиница отличалась бесплатным доступом к беспроводному интернету, более просторным номером и наличием фитнес-центра. Я по достоинству оценил эти дополнительные особенности, но для меня они не были обязательными условиями, чтобы остановиться там. Вместе с тем чем больше отличительных особенностей вроде этих предлагает гостиница, тем охотнее я в ней останавливаюсь. Наконец, в данной гостинице меня порадовали два аспекта: тренажеры «беговая дорожка» со встроенными телевизорами в фитнес-центре и бесплатная бутылка воды, ежедневно оставляемая в моем номере.

Я могу разбить особенности этого гостиничного номера на следующие категории:

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

• Чем больше, тем лучше: удобство кровати, размер номера, разнообразие и количество тренажеров в фитнес-центре.

• Приятные: встроенные телевизоры на тренажерах «беговая дорожка», бесплатная бутылка воды в номере ежедневно.

 

Модель удовлетворенности клиентов Кано

 

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

• пороговые, или обязательные, функции;

• линейные функции;

• привлекательные функции.

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

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

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

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

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

Поскольку обязательные функции необходимы продукту, чтобы занять рыночный сегмент, акцентировать внимание следует на приоритетности разработки всех пороговых функций. Нет нужды разрабатывать обязательные функции продукта в первых итерациях релиза. Вместе с тем в силу того, что пользователи считают эти функции обязательными, они должны быть реализованы до выпуска готового продукта. Не забывайте при этом, что может быть вполне приемлемой частичная реализация обязательных функций, поскольку прирост удовлетворенности клиентов быстро падает после достижения базового уровня поддержки таких функций. Например, я пишу эту книгу в издательской системе Adobe FrameMaker, которая поддерживает минимальную функцию «отмена», обеспечивая возврат лишь на один уровень. С моей точки зрения, ее разработчики продвинулись со своей одноуровневой функцией «отмена» довольно далеко по оси удовлетворенности клиентов, однако я бы предпочел, чтобы этих уровней было намного больше.

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

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

 

Оценка тем по модели Кано

Самый простой подход к использованию модели Кано в agile-проекте — анализ всех тем и их грамотная разбивка по типам. Намного лучше, однако, определить тип каждой темы совместно с клиентами или пользователями. Это на удивление легко, поскольку можно использовать письменный опросный лист. Для точной приоритизации требований опросный лист, возможно, придется направить 20–30 пользователям (Griffin and Hauser, 1993).

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

1. Мне это нравится.

2. Я ожидал, что это будет выглядеть так.

3. Мне безразлично.

4. Я могу смириться с этим.

5. Мне это не нравится.

В качестве примера вспомним наш веб-сайт SwimStats. Допустим, мы собираемся добавить три новые функции:

• Возможность видеть график результатов пловца в соревнованиях прошлого сезона.

• Возможность для пловцов размещать информацию о своей специализации.

• Возможность для любого зарегистрированного члена сайта загружать фотографии.

Чтобы определить типы этих функций, мы проводим опрос потенциальных пользователей, задавая им следующие вопросы:

• Если бы была возможность построить график результатов пловца в соревнованиях прошлого сезона, как бы вы к этому отнеслись?

• Если бы не было возможности построить график результатов пловца в соревнованиях прошлого сезона, как бы вы к этому отнеслись?

• Если бы у пловцов была возможность размещать информацию о своей специализации, как бы вы к этому отнеслись?

• Если бы у пловцов не было возможности размещать информацию о своей специализации, как бы вы к этому отнеслись?

• Если бы была возможность загружать фотографии, как бы вы к этому отнеслись?

• Если бы не было возможности загружать фотографии, как бы вы к этому отнеслись?

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

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

 

Категоризация ответов

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

Если повторить этот процесс с 20–30 пользователями, то их ответы можно сгруппировать и определить распределение, как показано в табл. 11.1. Анализ таблицы показывает, что построение графика результатов соревнований является одномерной (линейной) функцией, а загрузка фотографий — обязательной функцией.

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

 

Относительное взвешивание: еще один подход

Карл Вигерс (Wiegers, 1999) рекомендует подход, аналогичный подходу Кано, где учитываются и положительное влияние присутствия функции, и отрицательный эффект ее отсутствия. Вместо использования опросного листа этот подход предлагает опираться на экспертную оценку. Команда коллективно под руководством владельца продукта оценивает каждую предлагаемую для включения в следующий релиз функцию. Функция оценивается с точки зрения выгод, которые принесет ее реализация, а также с точки зрения потерь, которые возникнут при ее отсутствии. Как и оценки с использованием пунктов и идеального времени, оценки выгод и потерь являются относительными. Применяется шкала от 1 до 9. В табл. 11.2 на примере функций SwimStats показано, как это осуществляется.

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

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

Суммарное значение в колонке «Общая стоимость» (в нашем случае 33) представляет стоимость реализации всех функций. Для расчета относительного вклада каждой функции разделите ее общую стоимость на суммарное значение колонки «Общая стоимость». Например, построение графика результатов соревнований имеет стоимость 14. Общая стоимость всех функций составляет 33. Деление 14 на 33 дает 0,42, или 42 %. Это означает, что возможность построения графика результатов соревнований представляет 42 % общей стоимости всех перечисленных функций.

В следующей колонке, «Оценка», приведена оценка в пунктах или идеальных днях. Как и в случае «Общей стоимости», значения этой колонки суммируются (в нашем случае 61), после чего определяется процентная доля каждой оценки (колонка «Затраты, %»). В этом примере построение графика результатов соревнований оценено в 32 пункта или идеальных дня. Сумма трех оценок составляет 61 пункт или идеальный день. Поэтому возможность построения графика результатов соревнований представляет 53 % затрат на все три истории (32 / 61 = 0,53).

Значения в последней колонке, «Приоритет», определяются путем деления стоимости в процентах на затраты в процентах. Более высокие значения представляют более высокие приоритеты, поскольку соответствующие функции создают более значительную стоимость на затраченные на них силы и время. Это ясно видно в табл. 11.2 на примере функции размещения информации о специализации. Данная функция приносит немногим более половины стоимости функции построения графика результатов соревнований (общая стоимость 8 по сравнению с 14), однако на ее реализацию требуется всего одна четверть соответствующих затрат (оценка 8 по сравнению с 32). Из-за высокого отношения стоимости к затратам возможность размещения информации о специализации имеет наивысший приоритет в настоящем анализе.

Важность включения относительных потерь

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

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

Это наглядный пример функции с относительными выгодами, равными 1, и относительными потерями, равными 9.

 

Резюме

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

1. Объем и значимость обучения и нового знания, созданного в результате разработки функций.

2. Величину риска, ликвидированного в результате разработки функций.

3. Финансовую стоимость использования функций.

4. Затраты на разработку (и, возможно, поддержку) новых функций.

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

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

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

 

Вопросы для обсуждения

1. Назовите сравнительные достоинства анализа Кано и относительного взвешивания в вашей организации.

2. Какие привлекательные функции предполагается включить в ваш текущий проект?

3. Можно ли сказать, что ваш текущий проект имеет оптимальное соотношение привлекательных, линейных и обязательных функций?

 

Глава 12

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

 

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

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

 

Когда нужно разбивать пользовательскую историю

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

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

 

Разбивка по границам данных

Лучше всего разбивать большие пользовательские истории по данным, которые будут поддерживаться. Например, в одном из проектов команда разрабатывала продукт, предназначенный для сбора финансовой информации. Она начала с одной крупной пользовательской истории: «Как пользователь я могу вводить информацию из моего баланса». Баланс в данном случае мог иметь очень много полей. На самом высоком уровне в нем находятся активы и пассивы. Активы содержат такие статьи, как денежные средства, ценные бумаги, объекты недвижимости, автомобили, кредиты. Система позволяла пользователю работать с этим балансом на различных уровнях детализации. Пользователь мог ввести одну сумму, представляющую все его активы. Или он мог ввести более детальную информацию (подробное перечисление всех кредитов). Вывод множества полей на экран и взаимодействие между этими полями представляли задачу значительно более крупную, чем команда, по ее оценкам, могла реализовать за одну двухнедельную итерацию.

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

Следующая история звучала так: «Как пользователь я могу вводить детальную информацию по кредитам». Эта история должна была позволить пользователю вводить до 100 кредитов (это число обсудили, согласовали и сделали условием удовлетворенности на карточке истории). Данная история была крупнее, чем выглядела, поскольку решала несколько проблем с пользовательским интерфейсом, таких как количество новых рядов данных по кредитам, которые должны отображаться на экране. Эта история оказалась намного крупнее других, которые получились при разбивке исходной истории. Вместе с тем даже она была значительно меньше исходной истории, поскольку касалась поддержки детальных данных только по кредитам. Историю, связанную с кредитами, сделали образцом для многих других пользовательских историй, которые разбивались на части, вроде таких, как «Как пользователь я могу вводить детальную информацию по моим объектам недвижимости» и «Как пользователь я могу вводить детальную информацию по моим денежным авуарам, включая текущие и сберегательные счета».

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

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

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

В некоторых случаях большую историю можно значительно уменьшить, удалив из основной истории обработку исключительных или сбойных ситуаций. Допустим, вы работаете над системой для обработки погашений кредитов и имеете такую пользовательскую историю: «Как заемщик я хочу иметь возможность погасить мой кредит». Когда команда обсуждала эту историю, владелец продукта подчеркнул, что в случае нечаянной отправки заемщиком чека, превышающего сумму непогашенного остатка, необходимо распечатать чек на возвращаемую сумму и отправить обратно заемщику. Он добавил, что это относится только к суммам более $2. Эту историю можно разбить на следующие, более мелкие истории:

• Как заемщик я хочу иметь возможность погасить мой кредит. Примечание: допускаются переплаты.

• Как заемщик я в случае ненамеренной переплаты получаю возврат излишка, если он превышает $2.

 

Разбивка по операционным границам

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

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

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

Разбивайте большие истории на основе операций, которые выполняются в пределах истории.

Общий подход к этому заключается в разбивке истории по границам обычных CRUD-операций — создание, чтение, редактирование и удаление. Чтобы понять, как это работает, предположим, что вы создаете систему SwimStats, а команда готова к реализации такой истории: «Как тренер я могу управлять пловцами в моей команде». Команда разработчиков обсуждает историю с тренерами/пользователями и выясняет, что тренер под этим понимает возможность добавлять новых пловцов, редактировать существующие данные по пловцам и удалять записи о пловцах, которые ушли из команды. Подобная первоначальная история легко разбивается на три более мелкие истории:

• Как тренер я могу добавлять новых пловцов в мою команду.

• Как тренер я могу редактировать информацию о пловцах, входящих в мою команду.

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

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

Разбивайте большие истории на отдельные CRUD-операции.

 

Удаление сквозной функциональности

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

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

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

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

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

Это подводит нас к следующему правилу:

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

 

Несоблюдение требований к быстродействию

При разработке программного обеспечения мы нередко забываем (или игнорируем) совет Кернигана и Плоджера: «Сделайте это работоспособным, а затем повышайте быстродействие» (Kernighan and Plauger, 1974). Несколько лет назад я работал над проектом по воспроизведению графиков цен фондового рынка. Веб-пользователи должны были запрашивать график по биржевому символу (тикеру) акции. Наша программа должна была затем загружать исторические цены этой акции (за разные периоды от текущего дня до последних пяти лет) и строить линейный график движения акции. В число условий удовлетворенности, связанных с этой функцией, входили точность линии, восполнение пропусков данных и быстродействие. Для достижения целевого быстродействия мы должны были кэшировать наиболее часто запрашиваемые графики и перезаписывать каждый из них раз в минуту. Поскольку кэширование составляло значительную часть трудозатрат на разработку этой новой функции, мы выделили его в новую пользовательскую историю и включили в план следующей итерации. В общем смысле этот подход можно применять к любому нефункциональному требованию, в результате мы получаем следующее правило:

Попробуйте разбивать большие истории, разделяя функциональные и нефункциональные аспекты на отдельные истории.

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

 

Разбивка историй со смешанным приоритетом

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

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

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

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

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

Разбивайте большую историю на более мелкие, если маленькие истории имеют разные приоритеты.

 

Не разбивайте историю на задачи

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

• Программирование пользовательского интерфейса.

• Написание среднего яруса.

Избежать этого соблазна лучше всего помогает рекомендация Ханта и Томаса (Hunt and Thomas, 1999) применить к системе так называемый подход «трейсер буллет» (tracer bullet). Трейсер буллет затрагивает все слои функции. Это может означать поставку частично реализованного пользовательского интерфейса, среднего яруса и базы данных. Поставка связного подмножества всех слоев функции почти всегда лучше поставки одного полного слоя. Это дает нам следующее правило:

Не разбивайте большую историю на задачи. Вместо этого постарайтесь применить ко всей истории подход «трейсер буллет».

 

Избегайте соблазна добавить взаимосвязанные изменения

После разбивки истории и доведения ее до подходящего размера не усугубляйте ситуацию, добавляя работу в историю. Нередко возникает соблазн добавить так называемые взаимосвязанные изменения. Мы говорим себе: «Раз уж я работаю с этой программой, почему бы не внести в нее другие давно напрашивающиеся изменения». Под ними может подразумеваться исправление обнаруженных ошибок или решение какой-либо старой проблемы попутно с работой над отдельной задачей в этой же части программы. Вместе с тем приоритетность таких действий должна определяться точно так же, как приоритетность других функций. Другими словами, что имеет более высокий приоритет — растянувшееся на полдня устранение ошибки годичной давности или затрата такого же количества времени на что-нибудь другое? Ответ, понятно, полностью зависит от контекста. Таким образом, мы получаем последнее правило этой главы:

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

 

Объединение историй

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

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

 

Резюме

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

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

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

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

 

Вопросы для обсуждения

1. Есть ли в вашем текущем или другом проекте пользовательские истории, которые трудно поддаются разбивке? Как бы вы подошли к их разбивке теперь?

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