Жизненный цикл программного обеспечения
Источник нашей мудрости - наш опыт, источник нашего опыта - наша глупость.
В начале развития компьютерной индустрии проблема написания программ относилась к области искусства и состояла в том, чтобы получить "работающую" (доходящую до своего завершения) программу. Лишь затем программисты добивались от неё необходимых результатов путём длительной отладки и доработки. При этом было принято считать, что ни одна большая программа не может быть свободной от ошибок. Однако со временем появилось множество больших программ, которые должны были работать и работали годами, не выявляя никаких отклонений от требований. Но проходили годы, изменялась окружающая среда и изменялись требования. "Хорошие" работающие программы требовали модификации.
Важным толчком к совершенствованию методов разработки программ стало разделение пользователей на два класса: тех, кто пишет программы, и тех, кто решает с помощью этих программ прикладные задачи. Не будем забывать в первой группе так называемых системных программистов, которые пишут инструментальные программы (трансляторы, редакторы, операционные системы и т.п.) для других программистов. Таким образом программы стали отчуждаться от своих разработчиков. Они начали становиться самостоятельным продуктом.
Существенный качественный скачок стал возможен в семидесятых годах прошлого столетия. В 1969 году Эдсгер Дейкстра опубликовал статью "Структурное программирование" [3]. Это событие ознаменовало начало десятилетия напряжённого труда над инженерными методами, которые в корне изменили представления о подходах и тех возможностях, что открыты человеку в сфере разработки программного обеспечения (ПО). Благодаря структурному программированию и правильно поставленному процессу пошаговой разработки стало возможным создание действительно больших программных систем.
Расширение области применения вычислительной техники приводило к росту сложности ПО, ужесточению требования к надежности программ и, соответственно, росту времени построения программной системы и численности команды разработчиков. Возникла самостоятельная задача управления программными проектами, которая была разрешена путём построения методологии разработки программного обеспечения, включающей в себя описание процесса, организации работ, методов и инструментальных средств [4].
1.1. Общее описание жизненного цикла
Проектирование любой программной системы включает в себя несколько этапов или процессов, и чем лучше поставлено управление проектом, тем ярче они выражены [5]. Методология проектирования программных систем описывает процесс создания и сопровождения программного обеспечения в виде жизненного цикла (ЖЦ) разработки, представляя его как некоторую последовательность стадий и выполняемых на них процессов.
Для каждого этапа определяются состав и последовательность выполняемых работ, критерии начала и завершения этапа, получаемые результаты, методы и средства, необходимые для выполнения работ, роли и ответственность участников и т.д. Такое формальное описание ЖЦ разработки позволяет спланировать и организовать процесс коллективной работы, а также обеспечить управление этим процессом.
Понятия жизненного цикла и модели жизненного цикла несколько отличаются, однако термин "жизненный цикл" часто используется в смысле "модели жизненного цикла". Модель жизненного цикла разработки ПО - обобщенная структура, содержащая процессы, действия и задачи, которые осуществляются в ходе разработки, функционирования и сопровождения типового программного продукта в течение всей жизни системы, т.е. от определения требований до завершения ее использования.
На данный момент можно выделить следующие часто упоминаемые и используемые модели жизненного цикла:
- каскадная модель;
- процессная или поэтапная модель с промежуточным контролем;
- итерационная модель.
1.2. Каскадная модель
Каскадная модель (или, как ее еще называют, водопадная) (рис. 1.1) рассматривает последовательное выполнение всех этапов проекта в строго фиксированном порядке. Эта модель происходит от структуры диаграммы Ганта для поэтапного процесса. Переход на следующий этап означает полное завершение работ на предыдущем этапе. Модель подчеркивает, что результаты, полученные в ходе выполнения одного этапа, используются для выполнения следующего этапа.
Марри Кантор [7] отмечает ряд важных аспектов, характерных для каскадной модели. Каскадная схема включает несколько важных операций, применимых ко всем проектам:
- составление плана действий по разработке системы;
- планирование работ, связанных с каждым действием;
- применение контрольных этапов отслеживания хода выполнения действий.
При разработке относительно простых программных систем каждое приложение представляло собой единый, функционально и информационно независимый блок. Для разработки такого типа приложений эффективным оказался каскадный способ. Каждый этап завершался после полного выполнения и документального оформления всех предусмотренных работ.
В результате можно выделить следующие положительные стороны применения каскадного подхода:
- результат каждого этапа - законченный документ, отвечающий критериям полноты и непротиворечивости;
- заранее заданная последовательность этапов упрощает задачу планирования и позволяет вести контроль сроков завершения каждого этапа.
Каскадный подход хорошо зарекомендовал себя при построении простых систем, когда в самом начале разработки можно достаточно точно и полно сформулировать все требования к системе. Основным недостатком этого подхода является то, что, как показывает практика, реальный процесс создания сложной системы никогда полностью не укладывается в такую жесткую схему из-за большой динамики корректировок и уточнений, которые могут поступать как в результате дальнейшего развития проекта, так и извне в качестве новых требований и уточнений [9].
"Основное заблуждение каскадной модели состоит в предположениях, что проект проходит через весь процесс один раз, архитектура хороша и проста в использовании, проект осуществления разумен, а ошибки в реализации устраняются по мере тестирования. Иными словами, каскадная модель исходит из того, что все ошибки будут сосредоточены в реализации, а потому их устранение происходит во время тестирования компонентов и системы" [10].
Порой для улучшения характеристик каскадной модели в нее включают возможность возвратов на ранее выполненные этапы (рис. 1.2). Межэтапные корректировки позволяют учитывать реально существующее взаимовлияние результатов разработки на различных стадиях разработки. Даже на уровне модели видно, что самыми трудоемкими являются возвраты на уровень уточнения исходных требований.
Одна из проблем такой модели ЖЦ разработки заключается в отсутствии возможности оценить конечный результат до завершения всего процесса разработки ПО. Как показывает практика, будущие пользователи охотнее вносят изменения и уточнения в ходе оценки какого-либо прототипа системы (которого в данной модели ЖЦ не строится).
Одним интересным вариантом развития поэтапной модели является V-образный жизненный цикл (рис. 1.3). В этой модели акцент делается на работы, связанные с верификацией документов разработки. Нисходящая ветвь модели описывает собственно разработку программной документации: требования к ПО, функции программных элементов, архитектуру - связи программных функций, программный код. Восходящая ветвь - этапы верификации.
Применение V-образной модели жизненного цикла позволяет сконцентрировать внимание на проверке результатов разработки, точно спланировать, какие свойства программного обеспечения будут исследоваться, на каких этапах и на основании какой документации. Обычно обращение к данному виду модели связано с повышенными требованиями к качеству результатов разработки. Именно такой подход к выбору модели жизненного цикла разработки характерен для бортовых авиационных систем, систем управления космическими аппаратами, разработки встроенного ПО.