В конце каждой итерации мы можем указать команде разработки другое направление, отличное от того, что задумывалось ранее. На самом деле, вероятность этого высока. Изначально у нас есть всего лишь видение или преимущество, которым мы хотим воспользоваться. Команда разработки создает для нас приложение, содержащее только важнейшие аспекты будущего продукта. Мы смотрим на приложение, а затем начинаем думать, как его использовать, что надо добавить к инкременту, чтобы сделать его более удобным. В некоторых областях это требует внесения корректировок в середине разработки, так случается с каждой итерацией.
Каждый разработанный нами инкремент побуждает нас обдумывать более творческие либо более конкретные пути реализации идей и видения. Это заставляет нас начать диалог с командой разработки: мы можем совместно искать пути и изменения, позволяющие добиться наилучшего результата от следующей итерации.
Мы можем обнаружить, что наша идея нереалистична: отсутствует необходимая технология, или нам не нравятся результаты, или мы обнаруживаем, что цена будет слишком высокой. В зависимости от наших выводов мы можем остановиться на этом этапе и больше не тратить деньги, пока не найдем более реалистичное решение. Успешные проекты те, на которые деньги не тратятся напрасно.
Иногда одной итерации достаточно, чтобы разработать то, чем уже можно пользоваться, пока мы направляем команду разработчиков развивать более широкий функционал. Мы можем встраивать больше производительности и функционала итерация за итерацией, так как у нас есть преимущество более полного использования. Каждый инкремент накладывается на предыдущие. Когда результат работы команды разработки признается правильным, мы выпускаем релиз программного обеспечения, и им начинают пользоваться. Рисунок 2.2 иллюстрирует несколько итераций.
Рис. 2.2. Несколько итераций создают инкремент дополнительной функциональности
Мы придумали эмпирический процесс разработки программного обеспечения и выбираем, что делать дальше в конце каждой итерации, держа в уме нашу цель и рассматривая, что уже было разработано. Мы можем экстраполировать вероятную стоимость и срок поставки продукта, чтобы решить, хотим ли мы продолжать. Мы называем это итеративно-инкрементальным процессом, и это основа Scrum. Мы описали, как это работает и почему это может называться «программное обеспечение за 30 дней». Теперь давайте посмотрим, решает ли данный процесс проблемы, которые мы нашли в каскадном, или предиктивном, процессе.
Решает ли эмпиризм наши проблемы?Решает ли наше эмпирическое решение проблемы каскадного метода? Давайте оценим новый процесс в болевых точках, обнаруженных в каскадном методе.
Проблема 1 каскадного процесса: выпуск продукта занимает все больше и больше времени. Наши релизы будут состоять из множества объединенных инкрементов, разработанных последовательно, итерация за итерацией. Мы можем остановить итерации, когда захотим. Например, когда ценность продукта окажется максимальной, особенно если учесть, что более половины функционала программного обеспечения используется редко или никогда. Мы также можем остановиться и выпустить продукт, когда достигнута дата релиза или исчерпан бюджет. Мы накопили самые ценные инкременты в конечном результате.
Проблема 2 каскадного процесса: срыв графиков релизов. Наш график разработки не может сдвинуться более чем на 30 дней, так как это максимальная длительность одной итерации. Мы выпускаем накопленные инкременты, когда достигаем даты релиза. Мы не выделяем итераций для построения малозначительного функционала, что позволяет выпускать законченную систему гораздо раньше, чем обычно. При использовании традиционного метода разработки программного обеспечения только менее 50 % функционала используется часто. Мы не разрабатываем этот функционал.
Проблема 3 каскадного процесса: создание стабильной версии перед релизом занимает все больше и больше времени. Каждая итерация производит законченный, готовый к работе прирост функционала. Каждый последующий инкремент интегрируется с инкрементами всех предыдущих итераций, он также полностью завершен и готов к использованию. Перед релизом не требуется дополнительной работы по стабилизации, так как эта работа уже была выполнена.
Проблема 4 каскадного процесса: планирование занимает слишком много времени и выполняется неправильно. Начальное планирование сводится к постановке цели и определению наиболее ценных функциональных возможностей, производительности и особенностей, необходимых для ее достижения. Затем определяются ориентировочная стоимость и срок разработки. Планирование до первой итерации, как правило, занимает 20 % времени от того, что обычно мы привыкли тратить на планирование для каскадного, или предиктивного, метода. Мы планируем детальные требования для каждой итерации только непосредственно перед ее началом. Это планирование перед итерацией называется «точно в срок», и в него могут включаться требования, возникающие во время проверки предыдущей итерации, и адаптироваться лучшие требования для следующей.
Проблема 5 каскадного процесса: изменения трудно вносить в процессе разработки. В итеративно-инкрементальном процессе нет состояния середины процесса разработки. Новые требования могут возникать и быть добавлены перед каждой итерацией с минимальными затратами.
Проблема 6 каскадного процесса: ухудшение качества. Инкремент каждой итерации закончен и готов к использованию. Качество уже встроено. Каждый последующий инкремент также добавляет определенное качество. Нет этапа спешной стабилизации в конце проекта, когда нередко жертвуют качеством ради соблюдения сроков выпуска. Эта работа уже выполнена.
Проблема 7 каскадного процесса: авралы наносят моральный вред. Процесс стабилизации программного обеспечения перед выпуском исключен, как и работа в выходные и сверхурочная работа.
Как видите, итеративно-инкрементальный метод разработки, основанный на эмпирическом процессе, контролирует проблемы, которые обычно преследуют разработчиков программного обеспечения. При этом, чтобы определить нужды конкретных организаций, мы должны знать, как этими проектами управлять. Об этом мы поговорим в следующих главах и более детально в главе 6.
Работой можно управлять, используя всего три переменные. Первая (А) это требования, функциональные возможности, которые предоставит планируемое программное обеспечение. Вторая переменная (В) время, которое теперь мы измеряем в блоках по 30 дней. Третья переменная (С) законченная работа, которая измеряется в пригодных к применению функциональных возможностях или в количестве требований и функциональных возможностей, выполненных в каждый из 30-дневных периодов и совокупно.
Таким образом, можно создать график для управления проектом.
1. Бэклог требований по оси Y, или вертикальной оси. Работа по выполнению каждого требования разбита по размеру. Давайте предположим, что у нас есть пять требований. Каждое требует выполнения 2, 3, 5, 3 и 8 блоков работы. Они создают объем работы по оси Y из 21 блока. Блоки расположены в порядке, в котором вы хотите превращать их в пригодные к использованию функциональные возможности. Давайте, скажем, порядок сверху вниз будет 2, 3, 5, 3 и 8.
2. Время отложим по горизонтальной оси Х. Блоки по 30 дней, что составляет протяженность одной итерации.
3. Мы предполагаем, основываясь на предыдущем опыте, что команда разработки выполняет по пять блоков работы за каждую итерацию. Реальную производительность команды разработки выясним, когда начнем работу, а пока это всего лишь прогноз вчерашней погоды. Итак, мы предполагаем, что 20 блоков работы будут закончены за первые четыре итерации и последний фрагмент будет выполнен в течение пятой итерации.
2. Время отложим по горизонтальной оси Х. Блоки по 30 дней, что составляет протяженность одной итерации.
3. Мы предполагаем, основываясь на предыдущем опыте, что команда разработки выполняет по пять блоков работы за каждую итерацию. Реальную производительность команды разработки выясним, когда начнем работу, а пока это всего лишь прогноз вчерашней погоды. Итак, мы предполагаем, что 20 блоков работы будут закончены за первые четыре итерации и последний фрагмент будет выполнен в течение пятой итерации.
4. Объем выполненной работы и готовые к использованию функциональные возможности вычисляются в конце каждой итерации. Мы планируем, что первые два требования, которые состоят из двух и трех блоков работы, будут закончены в течение первой итерации. Мы предполагаем закончить следующий фрагмент функциональных возможностей, состоящий из пяти блоков работы, во второй итерации. К этому времени мы обычно уже корректируем планы относительно того, что же делать дальше. Мы уже видели первые два инкремента и часто на этом этапе находим непредвиденные или измененные требования для следующей итерации. Если такого не случилось, мы продолжаем, как планировалось. Тем не менее план и будущие требования без проблем могут изменяться в конце каждой итерации. Размер инкрементов измеряется в тех же единицах, что и требования по оси Y.
5. Команда разработки создала 3, 5 и 5 блоков функциональных возможностей в первые три периода времени. Получившийся график показан на рис. 2.3.
Рис. 2.3. Диаграмма сгорания работы
План, или прогноз, в начале работы показывает, что вы начали с 21 блока работы.
За каждую итерацию предполагалось выполнять пять блоков. Соответственно, мы нанесли это на график. Прогнозная линия на графике показывает, что все функциональные возможности планируется закончить за пять итераций.
Фактически завершенные требования показывают, что три блока работы были выполнены в первую итерацию, пять блоков во вторую и еще пять в третью. Мы показали прогресс на графике как линию фактически выполненной работы. Если мы создадим прогнозную линию из этой точки, то обнаружим, что вся работа будет закончена к середине, а не к началу пятой итерации. Однако это всего лишь прогноз, а не уверенность. Эмпиризм предполагает, что мы не узнаем наверняка, сколько работы будет сделано, пока она не будет сделана. В первой итерации мы предполагали сделать пять блоков, но получилось реализовать только три. Технология оказалась не до конца проработана, одно из наших требований было не совсем четким, и один из разработчиков болел в течение нескольких дней. Мы изучили прогресс в конце первой итерации и решили, что возврат инвестиций все еще на должном уровне, проблемы первой итерации, скорее всего, не повторятся. Основываясь на этих расчетах, мы рискнули профинансировать следующую итерацию. Такая проверка и адаптация требований происходят в конце каждой итерации.