учебники, программирование, основы, введение в,

 

Жизненный цикл программного изделия и его модели

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

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

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

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


Таблица 6.1. Особенности традиционных и объектно-ориентированных схем жизненного цикла разработки программного изделия

Традиционные схемы

Объектно-ориентированная схема

Полностью завершенные фазы проектирования и программирования

Итеративно наращиваемые возможности. Традиционные фазы распределяются по итерациям

Продукт в конце периода разработки

Рабочие продукты на каждой итерации

Техническое описание как итог конструирования

Рабочее описание, дополняемое на каждой итерации

Последовательная разработка

Возвратно-поступательная разработка

Модули действий, операций

Иерархии классов объектов

Структурная, пошаговая детализация

Наследование, переопределение, полиморфизм

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

Жизненный цикл и методологии программирования
В конце предыдущего раздела мы затронули очень важный аспект жизненного цикла программного обеспечения: его связь с методологиями программирования. Вообще говоря, методологии — это инструмент, с помощью которого создание программного продукта превращается в упорядоченный процесс, а работа программиста становится более прогнозируемой и эффективной (см. лекцию 4). Для этого создается детальное описание процесса разработки системы, особое место в котором занимает планирование (аналогично другим инженерным дисциплинам). И именно потребность в таком упорядочении породила интерес к изучению понятия жизненного цикла.
Традиционным образцом для методологий программирования являются инженерные дисциплины, такие, например, как строительство и машиностроение, где особое внимание уделяется планированию, которое предшествует непосредственному материальному производству. Инженеры разрабатывают целый ряд чертежей, в которых точно указывается, что именно должно быть построено и как соединить все составляющие в единое целое. Во время работы над чертежами принимается много различных проектных решений. Затем чертежи передаются другой группе специалистов, часто вообще в другую компанию, которая будет заниматься собственно строительством. Принято считать, что строители в точности воспроизводят все, что было обозначено на чертежах. В действительности строители сталкиваются с некоторыми проблемами, однако, как правило, они вполне разрешимы.
Есть место в этом процессе и декомпозиции, т.е. разбиению задачи материального производства на подзадачи. Чертежи, где представлены отдельные элементы строительства, ложатся в основу подробного чертежа, который позволяет определить конкретные задачи и зависимости между ними. А это, в свою очередь, дает возможность рассчитать стоимость и временные рамки строительства в целом. Кроме того, здесь же подробно описывается, каким образом строители должны выполнять свою работу. Благодаря этому работа строителей становится еще менее интеллектуальной, хотя, разумеется, нередко требует очень хороших навыков ручного труда.
А правомерно ли переносить такой поход из сферы материального производства на программирование? Если да, то мы должны с самого начала разграничить два вида деятельности в этой области:

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

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

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика