Переход от каскадной разработки к итеративной - Четыре шага перехода к итеративной разработке

ОГЛАВЛЕНИЕ

Четыре шага перехода к итеративной разработке

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

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

Рассмотрим эти шаги более подробно.

Шаг 1. Создание функциональных прототипов на раннем этапе

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

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

Для каждого ключевого технического риска нужно спланировать прототип с целью уменьшить этот риск. Рассмотрим следующие примеры.

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

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

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

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

Шаг 2. Деление фаз подробного проектирования, выполнения и тестирования на итерации

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

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

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

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

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

Предположим, вы создаёте новое приложение, которое позволит заказчику вести работу с дефектами. Это многоуровневое приложение, которое будет работать поверх сервера WebSphere Application Server, а системой управления базами данных будет DB2. На первой итерации вы разрабатываете ряд сценариев, например, ввод простого дефекта без дополнительной информации. На второй итерации вы усложняете эти сценарии, например, дефект может влиять на последовательность производственных операций. На третьей итерации завершается создание набора функций ввода дефектов и обеспечивается полная поддержка нестандартных пользовательских записей, например, возможность сохранить частичную запись о дефекте, чтобы впоследствии вернуться к ней и продолжить работу с ней.

При таком подходе вы работаете со всеми подсистемами на всех итерациях, но на первой итерации главное внимание уделяется самым важным вещам, а на последних итерациях внимание уделяется менее важным и менее трудным вещам.

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

Шаг 3. Создание базовой версии действующей архитектуры на раннем этапе

Этот шаг можно рассматривать как более формальный и организованный шаг 1: Создание функциональных прототипов на раннем этапе Что такое «действующая архитектура»?

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

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

Но как придумать архитектуру эволюционного прототипа? Главное – сконцентрироваться на самых важных вариантах использования, примерно от 20% до 30% всех услуг, которые системы должна предоставлять конечным пользователям. Далее приведены некоторые способы для определения самых важных вариантов использования.

  • Функциональность – это ядро приложения, она зависит от ключевых интерфейсов. Архитектуру системы должен определять её ключевой набор функций. Обычно архитектор выявляет наиболее важные варианты использования, анализируя множество факторов: стратегия управления избыточностью, риск конфликта между ресурсами, риск недостаточно высокой производительности, стратегии защиты данных и т. д. Например, в системе, предназначенной для торговой точки, ключевыми вариантами использования будут следующие: а) подсчёт стоимость всех покупок и выдача чека, б) оплата; потому что система проверяет интерфейс к системе проверки кредитных карт – это критически важно с точки зрения быстродействия и способности выдерживать большую нагрузку;
  • Выбор вариантов использования, описывающих обязательные функции. Поставка приложения без ключевых функций бесполезна. Например, система ввода заказов неприемлема, если она не позволяет пользователям вводить заказы. Обычно специалисты в предметной области понимают, какие ключевые функции требуются пользователям (основные варианты поведения, операции с данными при пиковой нагрузке, критически важные управляются транзакции и т. д.), поэтому могут помочь при определении критически важных вариантов использования;
  • Выбор вариантов использования, описывающих функции для той области архитектуры, которая не связана с критически важным сценарием использования. Чтобы учесть основные технические риски, разработчики должны понимать все области системы. Даже если какая-либо область архитектуры на первый взгляд не может создать высокий риск, за ней могут скрываться технические трудности, которые можно выявить только после проектирования, реализации и тестирования некоторых функций в данной области.

Первому и последнему критериям из приведённого выше списка архитектор должен уделить больше внимания; руководитель проекта должен сосредоточиться в основном на первых двух критериях.

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

Шаг 4. Применение итеративного процесса с управлением на основе рисков

Если вы выполнили описанные выше шаги 2 и 3, то очень близко подошли к модели «идеальной» итеративной разработки. Следующий шаг – объединить шаги 2 и 3, добавив управление разработкой на основе рисков и итеративную разработку. То есть описанный в RUP ряд итераций.

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

  • Обследование. Нужно хорошо понять, какой должна быть система, вникнув во все требования к системе, и определить объём работ. Уменьшить большинство рисков, составить технико-экономическое заключение о создании системы, получить одобрение со стороны представителей заказчика и их решение – начинать проект или нет;
  • Проработка. Обдумайте самые трудные технические риски: проектирование, реализация, тестирование, создание базовой версии действующей архитектуры, в том числе подсистем, их интерфейсов, ключевых компонентов, архитектурных механизмов (например, как организовать обмен данными между процессами, их сохранение). Проработайте главные технические риски, например, риски конфликта между ресурсами, риски недостаточно высокой производительности, риски недостаточной защиты данных. Для этого создайте и проверьте в деле реальный код;
  • Построение системы. На пути от действующей архитектуры к первой рабочей версии системы выполните основную часть работ по построению системы. Разверните несколько внутренних и альфа-версий, чтобы убедиться в том, что систему можно использовать, и она удовлетворяет потребностям пользователей. Завершите эту фазу развёртыванием полностью работающей бета-версии системы, включая установку, сопутствующую документацию и учебные материалы; помните, однако, что функциональность, производительность и общее качество системы наверняка придётся настраивать;
  • Сдача в эксплуатацию. Убедитесь, что программное обеспечение удовлетворяет потребности его пользователей. Среди прочего, для этого нужно протестировать продукт перед его выпуском и внести в него изменения в соответствии с отзывами пользователей. На этом этапе проекта отзывы пользователей должны быть сосредоточены на тонкой настройке продукта, на вопросах конфигурации, установки и удобстве использования; основные вопросы по структуре должны быть решены на предыдущих этапах проекта1.

Множество способов сделать эти шаги

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