Глава 3 Модели жизненного цикла корпоративных систем

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

В предыдущей главе был рассмотрен ряд моделей, используемых в разработке ПО, в частности модель Build-and-fix (модель неполного жизненного цикла, рис. 3.1), которая в силу своей простоты не пригодна для больших и сложных проектов, имеющих размеры более 1000 программных строк. Также была рассмотрена модель быстрого прототипирования, которая тоже несколько ограниченна, несмотря на то что включает в себя все необходимые стадии жизненного цикла: анализ и спецификацию требований, первичное и детальное проектирование, реализацию, модульное и сборочное тестирование, интеграцию, тестирование продукта, передачу его заказчику, вывод из эксплуатации. Несмотря на это, она несамостоятельна, потому что на самом деле этап тестирования (и индивидуальных модулей, и при сборке) недостаточен, документация неполная, и продукт, получаемый на выходе, лишь моделирует функциональность той «боевой» системы, разработка которой ведется.

Рис. 3.1. Модель Build-and-fx жизненного цикла ПО

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

Рис. 3.2. Каскадная модель жизненного цикла ПО

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

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

Рис. 3.3. V-модель жизненного цикла ПО на базе каскадной модели

Рис. 3.4. Быстрое прототипирование – модель жизненного цикла ПО

Рис. 3.5. «Зубья акула» – модель жизненного цикла ПО на базе модели быстрого прототипирования

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

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

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

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

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

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

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

Еще важное замечание: ряд продуктов (это может быть связано с заказчиками или конъюнктурой рынка, конкуренцией на рынке) требует революционного изменения самой концепции, основополагающих решений, которые закладываются в функциональные требования, план проекта и задание на релиз. Если заказчик меняет требования слишком часто, внезапно и значительно и нет возможности эти требования с ним согласовать и прийти к достаточно эволюционному их изменению, то получается, что каждый раз нужно не просто переработать значительную часть продукта, а, по сути, создать новый. Тем самым практически происходит переход к модели Build-and-fix. То есть нужно заново создать существенно отличающийся от предыдущего релиза продукт. При этом очень плохо, что в отличие от Build-and-fix, приходится заново осуществить полный жизненный цикл для каждого релиза: полностью описать требования в виде ТЗ, вести проектирование, т. е. создать огромное количество диаграмм прецедентов, диаграмм потоков данных, сценариев использования, которые их конкретизируют, диаграмм классов – сначала предварительных, а затем детальных, где заново оговариваются все начальные значения переменных, атрибуты и методы, взаимодействие между классами, методы-аксессоры, все существенные локальные и глобальные переменные, все алгоритмы, их реализация, структуры данных и т. д. Ведется тестирование: разрабатывается план тестирования – как продукт будет тестироваться, в каком порядке, какие тесты будут созданы для передачи продукта. Также можно сказать о пользовательской документации, документации для администраторов: продукт нужно будет по-другому устанавливать и настраивать, он будет иметь другой интерфейс, пользователи будут вынуждены работать с ним совершенно иначе, коды ошибок и вся остальная информация изменятся. И всю эту документацию также будет необходимо переделать. То есть речь идет о достаточно сложном варианте Build-and-fix, который подразумевает еще и полномасштабную документацию, отработку всех этапов жизненного цикла ПО. Поэтому такое производство, конечно, влечет огромное количество накладных расходов и является экономически нецелесообразным, и в условиях продукта, который быстро выходит за рамки исходной концепции, инкрементальная модель является недопустимой – будь то корпоративные или более простые системы.

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

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

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

Рис. 3.6. Инкрементальная модель жизненного цикла ПО

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

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

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

Рис. 3.7. Эволюционная модель жизненного цикла ПО

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

1) определить цели – продукт, деловые цели, понять ограничения, предложить альтернативы;

2) оценить альтернативы – анализ риска, прототипирование;

3) разработать продукт – детальный проект, код, unit test, интеграция;

4) спланировать следующий цикл – оценка клиентом, планирование проектирования, поставка клиенту, внедрение.

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

Рис. 3.8. Спиральная модель жизненного цикла ПО

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

Нужно заметить, что поскольку анализ рисков включает ряд существенных неопределенностей, которые заказчик для исполнителя обычно раскрывает далеко не в полной мере, спиральная модель достаточно хороша для внутренних проектов, когда разработчик и заказчик либо являются одним юридическим лицом, либо работают в рамках одной корпоративной структуры. Очень часто в больших корпорациях выделяется отдельная компания, занимающаяся ведением ИТ-проектов, например компания «Сибинтек» в составе ЮКОСа, компания «Итеранет» в группе компаний «Итера». Спиральная модель при такой организации взаимодействия, когда разработчик и заказчик находятся в рамках одной структуры корпоративного типа, – достаточно хорошее решение. В этом случае может осуществляться достаточно полная передача всей необходимой информации для оценки рисков, они могут оцениваться достаточно достоверно и поэтому грамотно и с минимальными затратами разрешаться.

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

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

Достаточно интересным является понятие видения (концепции) продукта, с этого вообще и начинается разговор о нем. Сначала должна появиться некоторая неформальная идея того, чем этот продукт будет принципиально отличаться от существующих, какие преимущества он принесет при реализации. При этом в ходе работы по этой модели, как и всегда, производится последовательная детализация программного продукта, и, естественно, видение является наиболее абстрактным представлением о нем. До того как начать разрабатывать продукт на основе этого представления, пусть даже неформализованного, готовится более точный документ, который описывает проектные спецификации. После этого происходит формирование проектной команды, готовится график работ: какие виды деятельности какой из ролей будут реализованы, на какой стадии, сколько это займет времени, какие будут вехи, результаты на каждом этапе изготовления продукта. Нужно заметить, что очень часто при разработке продуктов Microsoft проектная команда набирается именно под данный проект. И люди, которые участвуют в проекте на различных ролях – разработчиков, проектировщиков, документаторов, тестировщиков, встречаются только в тот период, когда изготавливают продукт. После этого часто бывает, что далее продукт существует независимо от них. Поэтому еще раз хочется подчеркнуть важность программной документации для обеспечения преемственности продуктов внутри линейки продуктов. У Microsoft, например, это линейки ОС Windows, приложений MS Office и др.

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

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

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

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

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

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

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

Таким образом, потенциально эта модель жизненного цикла перспективна, однако сложна и поэтому достаточно редко применяется для реализации больших корпоративных систем вне Microsoft. Ее важный недостаток – это то, что нужно уделять много времени синхронизации и стабилизации, т. е. тестированию и устранению тех ошибок, которые найдены тестами, особенно при не совсем хорошей дисциплине проекта или неполном представлении о процессах MSF. По сути, здесь имеется паразитный процесс. После известных событий 11 сентября компания Microsoft поставила безопасность приоритетом № 1 при производстве ПО. И любое ПО, которое производится сейчас, должно соответствовать внутренней модели жизненного цикла, принятой в Microsoft, которая называется SDL (security development lifecycle). При этом декларируется и поддерживается принцип «secure by design» – безопасность уже исходя из подхода к проектированию: сама модель проектирования строится таким образом, чтобы ПО было безопасным. Таким образом, паразитные процессы могут влечь положительные эффекты: увеличение стабильности, надежности, предсказуемости, масштабируемости создаваемого ПО, а для корпоративных систем это критически важные аспекты.

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

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

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

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

Еще одна модель – наиболее интересная и динамичная – это объектно-ориентированная модель. Речь пойдет о той ее разновидности, которую называют фонтанной. Это название будет понятно, если посмотреть на схему взаимодействия фаз этой модели.

В чем ее особенности? Если все предыдущие модели содержат изолированные, четко отделенные стадии жизненного цикла (анализ требований, спецификация требований, предварительное и первичное проектирование, детальное и окончательное проектирование, реализация и тестирование, сборка и интеграционное тестирование, тестирование продукта, приемочное тестирование и передача заказчику, сопровождение, вывод из эксплуатации), особенно четко это представлено в водопадной модели (пока нет подписи на документе, что предыдущая стадия завершена в соответствии с принятыми стандартами качества, следующая стадия не может быть начата), то в объектно-ориентированной модели принято достаточно интенсивное взаимодействие между различными фазами жизненного цикла. Более того, имеет место перекрытие фаз: перекрываются объектно-ориентированный анализ и спецификация требований, иногда – объектно-ориентированный анализ и проектирование (вместе это называется «object-oriented analysis and design», что, вообще говоря, в других моделях является разными фазами). В отличие от других моделей она не разделяет данные и действия: внутри класса атрибуты и методы равноправно взаимодействуют внутри класса. Во многом именно поэтому взаимодействие фаз и является важной особенностью объектно-ориентированного подхода.

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

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

Рис. 3.9. Объектно-ориентированная модель жизненного цикла ПО

Чем хороша объектно-ориентированная модель? Она хорошо ложится в доминирующий сегодня подход – ООП, который разработан для многих языков, начиная со Smalltalk и Simula-67, которые привели к созданию таких современных языков, как C++, Java, C# – родной язык. NET, основной для разработки корпоративных приложений. Таких языков достаточно много, и они весьма распространены. Поэтому объектно-ориентированная модель находит весьма широкое применение при производстве корпоративных систем. Чем это обусловлено? Тем, что объектно-ориентированный подход позволяет строить сколь угодно сложные системы за счет наследования и абстракции, того, что можно детализировать предметную область сколь угодно плавно. На основе примитивных классов небольшого размера можно представить грубую модель предметной области любой сложности.

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

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

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

Другие подходы к жизненному циклу включают в себя гибкие методологии, такие как Agile (рис. 3.10), Scrum (рис. 3.11), eXtreme Programming (рис. 3.12). Следует отметить, что направление этих подходов ортогонально моделям жизненного цикла. Они, в отличие от IBM Rational и MSF, применимы к проектам с большими неопределенностями, возможно, большими рисками, но меньшего масштаба, чем корпоративные информационные системы. С другой стороны, методологии – это параллельное направление проектирования систем, которое связано скорее с задачей проектного менеджмента, чем с задачей построения системной архитектуры.

Рис. 3.10. Жизненный цикл ПО, гибкие методологии, Agile

В заключение стоит еще раз отметить, что был рассмотрен ряд моделей – Build-and-fix, водопадная, быстрого прототипирования, инкрементальная, синхростабилизации, объектно-ориентированная, упоминалась эволюционная модель. Build-and-fix пригодна не для корпоративных проектов, а для небольших проектов с предсказуемым циклом развития и объемом порядка 1000 строк. Водопадная модель применима для корпоративных систем, обеспечивает четкую дисциплину проекта и хорошую управляемость, так как основана на большом количестве документов, которые производятся в ходе жизненного цикла, но в итоге из-за только одного прохода получившееся ПО может не соответствовать потребностям заказчика. Быстрое прототипирование несамостоятельно, в ряде случаев вызывает у разработчиков соблазн повторного использования быстро разработанного ненадежного, недокументированного кода. Способствует сопровождаемости и обеспечивает максимально ранний возврат инвестиций, так как приводит к консенсусу по поводу требований заказчика. Инкрементальная модель требует открытой архитектуры и может выродиться в Build-and-fix, но в целом удовлетворяет потребностям клиента из-за эволюционного процесса разработки продукта. Модель синхростабилизации обладает рядом преимуществ, но не получила широкого применения вне Microsoft. Спиральная модель пригодна в первую очередь для внутренних проектов, так как требует специфических знаний по оценке рисков. Объектно-ориентированная модель обеспечивает итерации и паралеллизм, но опять же при слабой дисциплине проекта может выродиться в модель Build-and-fix.

Рис. 3.11. Жизненный цикл ПО, гибкие методологии, Scrum

Рис. 3.12. Жизненный цикл ПО, гибкие методологии, eXtreme Programming (XP)

Данный текст является ознакомительным фрагментом.