WWW.DISS.SELUK.RU

БЕСПЛАТНАЯ ЭЛЕКТРОННАЯ БИБЛИОТЕКА
(Авторефераты, диссертации, методички, учебные программы, монографии)

 

Pages:     | 1 |   ...   | 2 | 3 || 5 | 6 |   ...   | 7 |

«ОСНОВАНИЯ ПРОГРАММИРОВАНИЯ УДК 519.682 Непейвода Н. Н., Скопин И. Н. Основания программирования Книга представляет собой первое издание в серии, предназначенной для студентов, готовящихся к работе по современным ...»

-- [ Страница 4 ] --

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

мы в отрыве от этого набора, вообще говоря, лишено смысла. Это указывает на естественные рамки переиспользования для данного стиля.

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

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

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

Обычными единицами переиспользования при любом стиле программирования являются процедуры. Именно они автономно описываются и, если оказываются независимыми от общего с другими компонентами контекста, то по сути дела становятся теми самыми черными ящиками, о которых только что шла речь.

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

Как ни странно, немногим лучше приспособлено к сочетанию со стилем переиспользования структурное программирование. Требования к структуре информационного пространства задачи и к согласованию с ним других компонентов программы обеспечивают регламентированные связи между подзадачами, а значит, облегчается (но не исчезает) задача выделения самостоятельных компонентов. В дополнение к полностью самостоятельным переиспользуемым компонентам здесь можно указать на переиспользование, при котором в новом применении обеспечивается необходимая часть контекста (т. е. переиспользуется компонент и эта часть контекста; смотри модули языков Modula 2 и Object Pascal). Модули можно рассматривать как серые ящики для структурного программирования. Возможности модуляризации достаточно хорошо исследованы и корректно реализованы в упомянутых выше языках.

ГЛАВА 3. ПРОГРАММИРОВАНИЕ С ПТИЧЬЕГО ПОЛЕТА

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

Рассмотрим простейший пример, который не выходит за рамки переиспользования черного ящика. Функция вычисления квадратного корня определена только для неотрицательных аргументов. Вопрос: нужна ли в переиспользуемой подпрограмме вычисления этой функции проверка? С одной стороны, она повышает надежность программирования, но с другой — оказывается избыточной, когда точно известно (можно доказать), что аргумент больше нуля.

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

На самом деле никакой крамолы в многовариантности нет.

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

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

При использовании сентенциального и функционального стиля возможности перестройки переиспользуемого компонента под ситуацию гораздо выше за счет более высокоуровневых принципов вычислений. Однако точных практических оценок этого пока что нет. Как правило, повторно используются крупные и содержательно полные фрагменты программ, чаще всего именно те, которые являют собой базовые механизмы, развивающие модель вычислений языка. Недостаточность опыта разработки больших производственТРИ ТЕХНОЛОГИЧЕСКИХ СТИЛЯ ПРОГРАММИРОВАНИЯ ных проектов с существенным использованием этих стилей вынуждают рассуждать о них лишь предположительно.

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

';

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

Проектирование с учетом повторного использования результатов в будущем возможно осуществлять на трех уровнях:

1. Уровень приложений. В ходе ведения проекта заботятся о том, чтобы при декомпозиции и разработке компонентов системы выявлялись компоненты-кандидаты на переиспользование. Эти компоненты выделяются в самостоятельные единицы и оформляются независимо от проекта;

2. Уровень инструментов. Разработка проекта практически всегда включает в себя создание инструментальных средств, поддерживающих унификацию: единые библиотеки общедоступных для проекта средств, общий контекст и единообразные средства доступа к нему, средства подГЛАВА 3. ПРОГРАММИРОВАНИЕ С ПТИЧЬЕГО ПОЛЕТА держки выполнения технологических соглашений и регламентов, шаблоны проектирования и др. Этот инструментарий или часть его во многих случаях может быть оформлен независимо от проекта для возможного переиспользования в виде библиотек;

3. Уровень решений. Ценность для переиспользования может представлять архитектурный уровень проекта. Хорошие архитектурные решения, как правило, допускают распространение за рамки конкретного проекта, в котором они появились. Это могут быть фрагменты, которые пригодны для использования в качестве образцов для других проектов, и тогда их переиспользование требует оформления соответствующего шаблона. Другой вариант независимого решения — каркас проекта, т. е.

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

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

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

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

3.9.2. Программирование от образцов Программирование от образцов — стиль, часто высокомерно игнорируемый специалистами, но тем не менее он является весьма распространенным (даже сами профессионалы им пользуются). Это — подход к разработке программ по заданным заранее шаблонам. Это скорее целый набор “вырожденных” стилей, каждый из которых выделяется в связи с тем, что в той или иной ситуации скрывается под понятием образец, фрейм, шаблон.

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

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

Можно указать следующие характерные случаи применения программирования от образцов:

• Дается программа, написанная в каком угодно стиле, в которой нужно кое-что изменить. Точно известно, в каких местах нужно это изменять.

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

• Дан набор программных инструментов, разработанный специалистами, и методика их применения, которая включает в себя схему состаГЛАВА 3. ПРОГРАММИРОВАНИЕ С ПТИЧЬЕГО ПОЛЕТА вления требуемой программы. В идеальном случае происходит применение содержательно описанного алгоритма, порождающего программу. Такой набор часто называется технологической или инструментальной системой для некоторого класса приложений.

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

• Программирование от макета. Разработчики быстро готовят прототип, который рассматривается как макет, который затем доводится до реального программного изделия. От макета в программной системе часто остается лишь система понятий, сам метод разработки полностью меняется (например, макет был написан на языке Prolog, а окончательная программа на Java). Макет (особенно в системах, поддержиывающих его представление в графической форме, таких, как UML [50]) часто становится частью документации готовой программы.

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

– семантические сети искусственного интеллекта;

– фирменная методика и технология, которая погружает один из предшествующих случаев в систему стандартизованных форм и документов. Пример RUP [88];

– табличное программирование, примеры которого приведены в данном пособии;

– компонентное программирование, например, с использованием XML или иного языка разметки (которая задает фрейм), и языка обработчиков разметки (разделение, как говорят на програмистском жаргоне, на парсер и обработчик). Это как раз то, что дает объектная модель документа.

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

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

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

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

ГЛАВА 3. ПРОГРАММИРОВАНИЕ С ПТИЧЬЕГО ПОЛЕТА

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

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

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

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

Рассмотрим подход к специализации, принятый в нынешней теории. Он показывает и возможности, и подводные камни.

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

3.9. ТРИ ТЕХНОЛОГИЧЕСКИХ СТИЛЯ ПРОГРАММИРОВАНИЯ данных, A — условие на вход (предусловие), C — область выходных данных, B(x, y) — связь вход-выход. C(y)&B(x, y) называется выходным условием (или постусловием) программы. При специализации программы мы можем преобразовать данное условие тремя способами.

a) Усилить условия на вход, чтобы программа применялась к лучше определенному множеству входных данных.

b) Расширить область выходных данных, чтобы дать возможность искать решение в более либеральных условиях.

c) Ослабить связь между входом и выходом.

Все эти три попущения могут применяться вместе. Частными случаями их являются добавление входных данных и удаление части выходных данных.

Как показано в работе [61], при специализации у нас возникают следующие основные преобразования:

1. Cпециализация элементарных действий: замена вызова некоторой процедуры либо метода на вызов более эффективной и лучше подходящей в данном частном случае процедуры.

2. Удаление вариантов и (или) действий, которые стали избыточны изза лучше обусловленного условия или более либерально поставленной 3. Спрямление вычислений, когда выясняется, что в частном случае мы достигли удовлетворительного результата намного раньше, и значительная часть промежуточной обработки может быть удалена.

4. Раскрытие вычислений, когда в рассмотренном частном случае примененная подпрограмма (на сей раз наша, а не заимствованная) может быть в свою очередь подвергнута специализации.

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

ГЛАВА 3. ПРОГРАММИРОВАНИЕ С ПТИЧЬЕГО ПОЛЕТА

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

Частный случай специализации, лучше всего исследованный в современной информатике, это смешанные вычисления, заключающиеся в следующем.

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

Классическая постановка задачи смешанных вычислений связана с рассмотрением программы как функции, отображающей вектор входных данных в вектор выходных (см. [33]). Если входные данные обозначить как x, выходные как y, а область значений переменной x обозначить Dx, то можно записать Если Dx = Dx Dx, причем значения аргументов из Dx фиксированы (для определенности, x = A), то можно попытаться автоматически построить программу, вычисляющую функцию Более строго задача смешанных вычислений формулируется следующим образом.

Пусть для языка L имеется частично-определенный алгоритм вычислителя V, который для любой программы P и начального состояния памяти X, если заканчивает работу, то приводит к заключительному состоянию памяти Иными словами, существует вычислительный автомат, исполняющий программы на данном языке.

Смешанным вычислением в языке L называется любой частично-определенный алгоритм M, который, если он определен для программы P и начального состояния памяти X, приводит к некоторому промежуточному состоянию памяти Y = MC(P, X) и к некоторой остаточной программе P = MG(P, X), где MC и MG удовлетворяют следующему равенству:

(Принцип частичного вычисления).

Таком образом, мы перерабатываем программу в остаток состояния памяти и в остаток алгоритма, который нужно вычислить в получившемся состоянии. Смешанное вычисление корректно, если на начальных состояниях определено отношение частичного порядка X Y, означающее, что состояние памяти X является частью Y, и всегда, когда определено. Сравните этот подход с подходом к определению рекурсии в Придожении А!

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

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

ГЛАВА 3. ПРОГРАММИРОВАНИЕ С ПТИЧЬЕГО ПОЛЕТА

оказались заменены на конкретные, эти конкретные значения удовлетворяют тем условиям, которые уже были известны. Так что, если мы уже знали, что данное поле находится в интервале между 0 и 5, то число, подставленное в качестве его значения, обязано принадлежать этому интервалу. Данные X назовем частичными, если для любых максимальных по отношению данных Y, таких, что X Y, выполнено X Y и имеются такие данные Z, что X Z = Y. Таким образом, частичные данные могут быть пополнены до любых полностью заданных, их расширяющих.

Пусть дан класс X частичных данных. Смешанное вычисление является равномерным относительно класса программ P, отношения между данными Y и класса частичных данных X, если есть алгоритм PEV(P, X, Y), определенный для каждой программы P P и для каждой пары данных X X X, такой, что выполнены равенства:

А вот это математическое определение прочитайте и разберитесь в нем сами!

Русский программист обязан хорошо владеть математическим языком, иначе он неконкурентоспособен на мировом рынке, особенно после 30 лет.

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

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

Программа 3.9. Y := 1;

while n>0 do Задача в том, как автоматически получить из программы 3.9.1, например, следующую программу, вычисляющую функцию Y = X 5, т. е. частичную программу для конкретного значения n = 5 и неопределенного значения X:

Для этого можно попытаться рассмотреть так называемую операционную историю вычисления программы 3.9.1 для n = 5:

{ 2} ( n > 0 ) равно TRUE:

{ 1} Y := 1;

{ 5} ( n > 0 ) равно TRUE:

{ 8} ( n > 0 ) равно TRUE:

{ 11} ( n > 0 ) равно FALSE Для дальнейшего удобно считать программу 3.9.1 только генератором операционной истории, полагая, что “фактическое” вычисление производится операторами линейной программы (строки 1, 4, 7, 10 истории, в которой остальные строки отражают вычисления управляющих условий). При этом полагается, что операторы универсальной программы выполняются либо обычным образом, если значения, входящих в них переменных определены (заранее фиксированы), либо, в противном случае, выдают в качестве результатов вычисления самих себя, т. е. выполняются ‘литерально’. Иными словами, операторы универсальной программы подразделяются на обычно выполняемые и задержанные. Выполнение последних не обязательно приводит к тождественной их выдаче в качестве результата: если оператор содержит

ГЛАВА 3. ПРОГРАММИРОВАНИЕ С ПТИЧЬЕГО ПОЛЕТА

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

Применение этих интуитивных соображений к приведенной выше истории приводит к следующей частичной истории:

( n > 0 ) равно TRUE:

Y := 1;

NOT ODD (n) равно TRUE:

( n > 0 ) равно TRUE:

NOT ODD (n) равно FALSE:

( n > 0 ) равно TRUE:

NOT ODD (n) равно TRUE:

( n > 0 ) равно FALSE и следующей остаточной программе очень близкой к программе (3.1).

Первый оператор программы (3.2) отличается от своего прообраза заменой терма Y на его значение. Следует заметить, что замена его на Y:= X возможна, но как результат трансформации программы, природа которой совсем иная, нежели обсуждаемые здесь механизмы преобразований. Эта замена правомерна в силу аксиоматики кольца целых чисел, а не как следствие частичного вычисления. Последний оператор является избыточным. Это можно обнаружить вполне регулярным образом, но опять не как следствие частичного вычисления.

Конец примера 3.9.1.

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

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

Еще одно замечание. Решение ‘заморозить’ X в программе 3.9.1 было произвольным, но коль скоро оно принято, все остальные операторы, попавшие в остаточную программу по индукции, были задержаны ‘вынужденно’, т. к.

их термы зависели от замороженной переменной X.

3.9. ТРИ ТЕХНОЛОГИЧЕСКИХ СТИЛЯ ПРОГРАММИРОВАНИЯ Что изменилось бы в этих построениях, если бы они исходили из неимперативной модели вычислений? Прежде всего, изменилось бы понятие истории вычислений, а вслед за ним и то, что понимается под остаточной программой. К примеру, в исходной программе на языке Prolog мы бы увидели соотношения, рекурсивно задающие последовательность утверждений, логическая подстановка которых ведет к цели: к получению значения данной функции от двух переменных X и n в качестве запрашиваемого утверждения.

Анализ истории подстановок при n = 5 покажет, что некоторые из утверждений становятся лишними, раньше распознаются тупики. Это дает основание для сокращения программы, но здесь практически ничего не достичь без объединения утверждений и их эквивалентных преобразований.

В функциональном языке история вычислений — это последовательность подстановок аргументов функций и применения функций к аргументам. Некоторые из этих действий приводят к выбору конкретного варианта продолжения процесса в зависимости от перерабатываемых данных, иногда они могут быть вычислены заранее, если имеются сведения о данных. Анализируя историю, как и в операционном случае, можно определить, как нужно преобразовать программу, чтобы были учтены эти сведения, и, таким образом, построить остаточную программу. Программа функции F(x,n), реализующая тот же алгоритм, что был представлен выше, при n = 5 за счет ликвидации разветвлений и раскрытия рекурсии приобретет примерно такой вид:

На Лиспе, например, этот вид превращается в (LAMBDA (x)(LAMBDA (t)(t*t*x)*(x*x))) Здесь специализация программы в первом приближении сводится к вычислению функций с частично определенными параметрами.

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

Не следует думать, что при написании универсальной программы можно совсем не заботиться о качестве. Так, если ваша программа вычисления функции Y = X n будет реализовывать прямолинейный алгоритм последовательного умножения на X, то бессмысленно ожидать, что с помощью универсального специализатора из нее получится остаточная программа с миниГЛАВА 3. ПРОГРАММИРОВАНИЕ С ПТИЧЬЕГО ПОЛЕТА мальным числом умножений. Скорее всего, при n = 5 у вас получится что-то вроде ((((x*x)*x)*x)*x).

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

И смешанное вычисление, и опциональная специализация — примеры статического вычисления программы. Это общее понятие включает и многие другие возможности. Рассмотрим их от простого к сложному.

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

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

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

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

ОБЩИЕ ВЫВОДЫ

§ 3.10.

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

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

ГЛАВА 3. ПРОГРАММИРОВАНИЕ С ПТИЧЬЕГО ПОЛЕТА

этим стилям накапливаются собственные типовые решения.

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

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

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

Большая часть таких стилей с трудом может быть систематизирована. Да это и не требуется! Нужно только хорошо осознавать, что особенности стилей не только неизбежны, но и желательны.

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

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

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

Другой вопрос, насколько они этой цели достигают.

Но авторам программ стоило бы помнить о том. что в Ватиканской канцелярии высшей похвалой документу является: «Он так хорошо написан, что невозможно понять, кто его автор.»

Локальные Глобальные Сентенциальный Второй уровень, представленный функциональным программированием и ООП, при разработке конкретных систем использует модули, написанные в стилях первого уровня.

Что касается событийного программирования, то после появления развитых систем поддержки визуального отображения программ, поддерживающиъх структуру многооконного интерфейса (прежде всего, таковыми стали системы Think Pascal и Think C++ для Macintosh, а затем их эстафкету подхватили Visual C++ и Delphi) его зачастую рассматривают как обязательный комплекс средств объектно-ориентированной системы программирования. Как мы могли убедиться, это все-таки дополнительные стилевые возможности.

Рассмотрим теперь, каким классам практических задач лучше всего соответствуют различные стили программирования.

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

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

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

Распознавание образов — автоматы.

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

ГЛАВА 3. ПРОГРАММИРОВАНИЕ С ПТИЧЬЕГО ПОЛЕТА

Статика графики — рекурсия в объектно-ориентированной форме. Динамика графики — автоматы в объектно-ориентированной форме либо событийное программирование. Опыт показывает, что достаточно сложная реальная программная система обязательно совмещает модули, написанные в разных стилях. Адекватный выбор стиля первого уровня для конкретных модулей обеспечивается прежде всего знанием особенностей каждого стиля и их назначения.

1. Что представляет собой первый цикл в программе 3.3.1? Какую схему программ он моделирует?

2. В программе 3.9.1 есть ошибка (по традиции появляющаяся с момента ее разбора А. П. Ершовым). Где ошибка и почему ее не обязательно исправлять для иллюстрации смешанных вычислений?

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

Глава Понятие жизненного цикла программного обеспечения и его модели

ВВЕДЕНИЕ

§ 4.1.

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

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

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

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

Программы, в отличие от чаще всего встречающихся в нашем обиходе искусственных объектов, или артефактов, являются в некотором роде идеГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ альными объектами, и на самом деле единственными чисто искусственными объектами, кроме математических конструкций, с которыми имеет дело человек. Например, машина сделана из реальных материалов, наследует их свойства, и уже по этой причине не может создаваться чисто логически, силами одной лишь мысли. А математический объект и программа сосотоят из информационных сущностей. В принципе они могут быть порождены чисто логически. Но и в том, и в другом случае чистая логика творения натыкается на реальные либо конвенциональные ограничения. Математический объект должен быть признан сообществом математиков, и поэтому должен вписаться в систему существующих математических объектов. Программа же создается на базе других программ и должна работать в их окружении. Сложность программного окружения такова, что разобраться в нем до конца невозможно, да оно вдобавок и меняется все время. Так что программное окружение играет сейчас для программ ту же роль, что конструкционные материалы и окружающая среда — для технических. И, конечно же, неустраним фактор пользователя. Все равно, делаете Вы программу для квалифицированных программистов либо для конечных пользователей, пользователь перепутает все, что возможно, и даже то, что невозможно, и затруднительно предсказать, что он может сотворить с программой. Но, тем не менее, программа наиболее близко, за исключением математическх структур, подходит к понятию настоящего искусственного объекта.

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

Ошибки возникают также от изменения условий использования программы.

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

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

Исторически развитие концепций жизненного цикла связано с поиском для него адекватных моделей. Как и всякая другая, модель жизненного цикла является абстракцией реального процесса, в которой опущены детали, несущественные с точки зрения назначения модели. Различие назначений примеВВЕДЕНИЕ Разработка Рис. 4.1. Разработка, использование и сопровождение программ нения моделей определяет их разнообразие.

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

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

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

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

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

В настоящей главе модели жизненного цикла представлены в виде, позволяющем рассматривать их, абстрагируясь от специфики разработки конкретных программных систем. Описываются традиционные модели и их развитие, приспособленное к потребностям объектно-ориентированного проектирования.

ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

МОДЕЛИ ТРАДИЦИОННОГО ПРЕДСТАВЛЕНИЯ

О ЖИЗНЕННОМ ЦИКЛЕ

§ 4.2.

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

• разработка и • сопровождение.

Фазы разбиваются на ряд этапов (см. рис. 4.2).

Разработка начинается с идентификации потребности в новом приложении, а заканчивается передачей продукта разработки в эксплуатацию.

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

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

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

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

ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

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

В рассматриваемой модели фаза разработки заканчивается этапом тестирования (автономного и комплексного) и передачей системы в эксплуатацию.

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

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

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

4.2.2. Классическая итерационная модель Общепринятая модель жизненного цикла является идеальной, т. к. только очень простые задачи проходят все этапы без каких-либо итераций — возвратов на предыдущие шаги технологического процесса. При программировании, например, может обнаружиться, что реализация некоторой функции очень громоздка, не эффективна и вступает в противоречие с требуемой от системы производительностью. В этом случае требуется перепроектирование, а может быть, и переделка спецификаций. При разработке больших неТРАДИЦИОННОЕ ПРЕДСТАВЛЕНИЕ традиционных систем необходимость в итерациях возникает регулярно на любом этапе жизненного цикла как из-за допущенных на предыдущих шагах ошибок и неточностей, так и из-за изменений внешних требований к условиям эксплуатации системы.

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

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

Классическая итерационная модель абсолютизирует возможность возвратов на предыдущие этапы. Однако это обстоятельство отражает существенГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ ный непреодолимый аспект программных разработок: стремление заранее предвидеть все ситуации использования системы и невозможность в подавляющем большинстве случаев достичь этого2. Все традиционные технологии программирования направлены лишь на то, чтобы минимизировать возвраты. Но суть от этого не меняется: при возврате всегда приходится повторять построение того, что уже считалось готовым.

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

4.2.3. Каскадная модель Более строгой разновидностью классической модели является так называемая каскадная модель, которую можно рассматривать в качестве показательного примера того, какими методами можно минимизировать возвраты.

Характерные черты каскадной модели:

• завершение каждого этапа (они почти те же, что и в классической модели) проверкой полученных результатов с целью устранить как можно Данное противоречие является типичным примером т. н. проблемного противоречия, противоречия между желаемым и действительным. Решение проблемных противоречий является стимулом творческой деятельности человека. Более того, задачу, которая требует творческого подхода, лучше всего формулировать в виде проблемных противоречий, максимально обостряя их. Именно тогда можно надеяться на то, что будет найдено действительно хорошее и адекватное решение. Методология использования проблемных противоречий в творческих рассуждениях была развита Г. С. Альтшуллером и советской школой теории решения изобертательских задач (ТРИЗ). Программистам и особенно преподавателям программирования настоятельно рекомендуется прочитать книгу Г. С. Альтшуллера [4]. Хотя методы ТРИЗ в большинстве своем прямо не могут быть применены при решении программистских задач, поскольку они в основном направлены на поиск элементарных решений, преодолевающих «сопротивление материала», методология подхода исключительно полезна для любого творческого человека, занимающегося созданием реальных систем (именно этим программисты, ученые и инженеры отличаются от гуманитариев).

большее число проблем, связанных с разработкой изделия;

• циклическое повторение пройденных этапов (как в классической модели).

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

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

Результат проектирования верифицируется, т. е. проверяется, что принятая структура системы и реализационные механизмы обеспечивают выполнимость специфицированных функций.

Реализация контролируется путем тестирования компонент, а после интеграции компонент в систему и комплексной отладки проводится аттестация, т. е. проверка-фиксация фактически реализованных функций системы, описание ограничений реализации и т. п.

В ходе эксплуатации и сопровождения изделия устанавливается, насколько хорошо система соответствует пользовательским запросам, т. е. осуществляется переаттестация.

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

ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

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

• оно противоречиво, т. е. содержит несовместные или невыполнимые требования;

• не выработаны критерии для выбора одного из возможных вариантов решения.

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

Строгая каскадная модель фиксирует два важных момента жизненного цикла:

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

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

ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

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

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

Наиболее последовательно такое дополнение классической схемы реализовано в модели Гантера [23] в виде матрицы «фазы — функции». Уже из упоминания о матрице следует, что модель Гантера имеет два измерения:

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

В модели Гантера отражено то, что выполнение функции на одном этапе может продолжаться на следующем. На рис. 4.6 представлено фазовое измерение модели. Жирной чертой (с разрывом и стрелкой, обозначающей временное направление) изображен процесс разработки3. Контрольные точки и наименования событий указаны под этой чертой. Они пронумерованы. Все развитие проекта в модели привязывается к этим контрольным точкам и событиям.

В данной модели жизненный цикл распадается на следующие перекрывающие друг друга фазы (этапы):

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

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

ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

Рис. 4.6. Фазовое измерение модели фазы — функции • исследования — этап начинается, когда необходимость разработки признана руководством проекта (контрольная точка 0), и заключается в том, что для проекта обосновываются требуемые ресурсы (контрольная точка 1) и формулируются требования к разрабатываемому изделию (контрольная точка 2);

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

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

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

• оценка — фаза является буферной зоной между началом испытаний и практическим использованием изделия. Она начинается, как только проведены внутренние (силами разработчиков) испытания изделия (контрольная точка 6) и заканчивается, когда подтверждается готовность изделия к эксплуатации (контрольная точка 9);

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

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

1. планирование, 2. разработка, 3. обслуживание, 4. выпуск документации, 5. испытания, 6. поддержка,

class='zagtext'> ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

7. сопровождение.

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

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

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

ИТЕРАТИВНЫЕ МОДЕЛИ ЖИЗНЕННОГО ЦИКЛА

§ 4.3.

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

ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

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

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

Функциональный стиль соответствует абстрактному (математическому) мышлению, объектно-ориентированный — образному (визуальному), сентенциальный — вербальному (словесному). Большие и успешные проекты, использующие итеративное развитие, имеются на базе каждого из этих стилей. Если ООП является стандартным методом индустриального программирования, то функциональное программирование является одним из главных методов сообщества Open Source, и в качестве итеративного проекта, реализованного на этой базе, можно сослаться хотя бы на EMACS (или, если Вы признаете лишь коммерческое программное обеспечение, на AUTOCAD).

Сентенциальный стиль в его PROLOGовском варианте послужил основой ряда крупных баз знаний.

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

Рис. 4.8. Учет итеративности в модели фазы-функции (фазовое измерение, показаны лишь некоторые возвраты) итеративный характер развития проекта.

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

4.3.1. Базовые технологические принципы итеративного проектирования Рассмотрим принципиальные моменты, которые стали трактоваться в итеративном подходе к развитию проектов по-иному в сравнении с последовательными методологиями.

I) Итеративность развития Начиная с фазы анализа и до завершения реализации, процесс проектирования строится как серия итераций, отбрасывая иллюзию о построении программы сразу и до конца, пронизывающую традиционные подГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ ходы. Каждая итерация является результатом разрешения противоречий между желаемым и достижимым, частично реализуя цели.

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

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

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

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

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

V) Ничто не делается однократно.

Последовательный подход предполагает, что анализ завершен перед конструированием, завершение которого предшествует программированию.

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

VI) Оперирование на размножающихся фазах подобно.

Как в начале проектирования, на последующих итерациях анализ предшествует конструированию, за которым следует программирование, тестирование и другие виды работ.

При итеративном проектировании в ходе наращивания функциональности обыкновенно выполняются вполне традиционные этапы:

1. Определение требований, или планирование итерации, — фиксируется, что должно быть выполнено на данной итерации в виде описания области, для которой планируется разработать функциональность на данной итерации, и что для этого нужно. Обычно этот этап включает отбор сценариев, которые должны быть реализованы на данной итерации;

2. Анализ — исследуются условия выполнения планируемых требований, проверяется полнота отобранных сценариев с точки зрения реализации требуемой функциональности;

3. Моделирование пользовательского интерфейса — коль скоро итерация должна обеспечивать функционально законченную реализацию, требуется определить правила взаимодействий, необходимые для активизации требуемых функций. Модель интерфейса представляет пользовательское представление поведения объектов данной итерации;

4. Конструирование — обычная декомпозиция проекта. Конструирование включает построение или наращивание иерархии понятий (например, системы классов, описания событий и определения реакции на них и т. д.) В ходе конструирования определяются понятия и их программные реализации, реализуемые и/или доопределяемые на данной

ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

итерации, и набор функций, которые обеспечивают решение задачи данной итерации;

5. Реализация (программирование) — программное воплощение решений, принятых для данной итерации. Необходимым компонентом реализации здесь считается автономная проверка соответствия составляемых модулей их спецификациям (в частности, должно быть обеспечено требуемое поведение объектов);

6. Тестирование — этап комплексной проверки результатов, полученных на данной итерации;

7. Оценка результатов итерации — этап включает работу, связанную с рассмотрением полученных результатов в контексте проекта в целом. В частности, должно быть выяснено, какие задачи проекта можно решать с учетом результатов итерации, на какие ранее поставленные вопросы получены ответы, какие новые вопросы возникают в новых условиях.

4.3.2. Итеративная модификация модели фазы-функции Этапы итеративного развития проекта остаются практически традиционными внутри одной итерации. Это позволяет описывать процесс итеративного наращивания как модификацию существующих моделей жизненного цикла. В настоящем разделе такая модификация осуществляется для модели фазы-функции Гантера.

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

1. Распределение реализуемых требований по итерациям.

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

2. Конструирование системы с учетом будущего ее развития, в первую очередь наращивания ее возможностей.

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

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

В новой схеме жизненного цикла появляется строго регламентированное расщепление, единственное для всей последовательности работ (см. рис. 4.9).

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

Любой итеративно развивающийся сложный проект строится на базе уже

ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

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

Таким образом, необходимо планирование и реализация переиспользования программного обеспечения. Конкретной реализацией планирования переиспользования обычно является выделение при выполнении этапа оценки общеполезных компонент и сохранение их в депозитарии проектов.

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

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

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

• требуется определить ближайшую задачу и перспективные задачи проекта.

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

• требуется выбрать критерии оценки результатов итераций. Эти критерии могут варьироваться в зависимости от направленности проекта, прикладной области и других обстоятельств.

Фаза завершения проекта (итерации) охватывает часть жизненного цикла, которая отражает деятельность разработчиков, связанную с рабочими продукГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ тами итерации, после получения результатов. Она аналогична традиционной фазе эксплуатации и сопровождения, однако есть и отличия, обусловленные тем, что объектно-ориентированный проект обычно имеет дело с иерархиями версий системы, отражающими наращивание возможностей. Данная фаза перекрывается с этапом оценки.

Традиционные работы фазы завершения включают в себя:

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

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

• выделение общих (т. е. не привязанных к проекту) переиспользуемых компонентов (обычно эти работы связываются с событием передачи системы на распространение — контрольная точка 10).

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

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

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

организацию нового проекта (быть может, специального), цель которого — учет новых требований.

Несколько слов о функциональном измерении в модифицированной для итеративного подхода матрице фазы — функции. Как было показано выше, целесообразно список технологических функций расширить за счет моделирования. Соответственно, следует определить в матрице Гантера строку интенсивностей для этой функции. В предположении о сохранении распределения интенсивностей других функций (см. рис. 4.7) распределение интенсивности для модифицированной модели жизненного цикла можно задать так, как это сделано на рис. 4.10, который показывает новый вид модели целиком (на рисунке контрольные точки жизненного цикла указаны своими номерами без пояснений).

Представленные распределения интенсивностей нельзя абсолютизировать.

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

ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

Контрольные Рис. 4.10. Модель фазы - функции, модифицированная для объектно-ориентированного развития проекта 4.3.3. Параллельное выполнение итераций Любой программный проект, заслуживающий привлечения менеджера для поддержки разработки, — процесс, развиваемый коллективно. Следовательно, уместно ставить вопрос, как должна отражаться в модели жизненного цикла одновременность деятельности исполнителей коллектива. По вполне понятным причинам, это является одним из мотивов разработки моделей.

В модели, следующей гантеровской схеме ‘фазы — функции’, это качество процесса разработки программного изделия отражено с помощью функционального измерения, показывающего, какие технологические функции выполняются одновременно. В рамках итеративного подхода явно выделяется еще один вид технологического параллелизма: одновременная разработка нескольких итераций разными группами исполнителей (словосочетание «разные группы» не надо понимать буквально — по существу, это групповые роли, и конкретная группа исполнителей вполне может одновременно отвечать за разработку сразу нескольких итераций).

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

• область недопустимого совмещения, когда выполнение одной работы непосредственно зависит от результатов другой работы;

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

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

Одновременность выполнения разных итераций можно представить в виде схем, показанных на рис. 4.11. На рис. 4.11а) приведена расшифровка этапов итераций. По сравнению с общей моделью (см. рис. 4.10), здесь представлено

ГЛАВА 4. ЖИЗНЕННЫЙ ЦИКЛ

Планирование Анализ Конструиров Программир Тестирова Оценка итерации (1-2, 7-8) (2-3) ание (3-5) ование (4-7) ние (6-7) (7-8) Рис. 4.11. Распараллеливание выполнения итераций проекта более мелкое дробление этапов: явно выделены планирование, которое для начальной итерации является частью общего этапа анализа осуществимости, и тестирование как перекрывающаяся часть общих этапов программирования и оценки.

Рис. 4.11б) демонстрирует три одновременно выполняемые итерации: вторая начинается в ходе выполнения программирования первой итерации с таким расчетом, чтобы ее этап программирования начался после окончания тестирования первой итерации. Планирование третьей итерации начинается одновременно с этапом программирования второй итерации.

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

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

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



Pages:     | 1 |   ...   | 2 | 3 || 5 | 6 |   ...   | 7 |


Похожие работы:

«Б А К А Л А В Р И А Т П.С. ГУРЕВИЧ ЭСТЕТИКА Учебное пособие КНОРУС • МОСКВА • 2013 УДК 17(075.8) ББК 87.7я73 Г95 Гуревич П.С. Эстетика : учебное пособие / П.С. Гуревич. — М. : КНОРУС, 2013. — 454 с. Г95 ISBN 978-5-406-00349-7 В учебном пособии дан краткий обзор истории эстетики, представлено изложение эстетической теории, основных идей и проблем классической эстетики, выраженных в ее главных категориях. Сделана попытка провести классификацию эстетических понятий, осветить новейшие эстетические...»

«Пособие по развитию навыков устной речи www.russie-aquitaine.com Учебное пособие по развитию устной речи Русский язык в ситуациях повседневного общения подготовлено авторским коллективом Ассоциации Россия-Аквитания (г. Бордо, Франция) в рамках европейского образовательного партнёрства программы Грюндтвиг. Mетодическая разработка адресована преподавателям РКИ, работающим со взрослой публикой в условиях ограниченного количества часов, а также обучающимся, желающим повысить практический уровень...»

«МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ НОУ ВПО МОСКОВСКАЯ АКАДЕМИЯ ЭКОНОМИКИ И ПРАВА Воронежский филиал УТВЕРЖДАЮ Директор Воронежского филиала д.т.н., профессор Заряев А.В.. 2013 г. Кафедра общегуманитарных и естественнонаучных дисциплин УЧЕБНО-МЕТОДИЧЕСКИЙ КОМПЛЕКС по учебной дисциплине ИСТОРИЯ ЗАРУБЕЖНОГО ГОСУДАРСТВА И ПРАВА по направлению: 030500.62 – Юриспруденция Воронеж Автор-составитель: Холодов О.М., к.п.н., доцент Рецензент: Чебаев В.Н., к.ю.н., доцент кафедры...»

«С.И. Л А З А Р Е В, Э. Н. О Ч Н Е В, О.А. АБОНОСИМОВ НАЧЕРТАТЕЛЬНАЯ ГЕОМЕТРИЯ ДЛЯ ПЕРВОКУРСНИКА ИЗДАТЕЛЬСТВО ТГТУ Министерство образования и науки Российской Федерации Тамбовский государственный технический университет С.И. Лазарев, Э.Н. Очнев, О.А. Абоносимов НАЧЕРТАТЕЛЬНАЯ ГЕОМЕТРИЯ ДЛЯ ПЕРВОКУРСНИКА Учебное пособие Тамбов Издательство ТГТУ УДК 519.1.(075) ББК В151.34я Л Рецензенты: Доктор технических наук, профессор Тамбовского государственного технического университета В.В. Леденев Доктор...»

«Тематика курсовых работ по курсу Уголовного права для студентов специальности Правоведение, Экономическое право для групп: 60201-04с, 60701-02с, 60206-07зт, 60201-02з Методические указания для написания курсовой работы Студент выбирает тему курсовой работы по последней цифре номера студенческого билета. При этом ему предоставляется определенная свобода выбора: можно выбрать одну из каждого десятка тем, порядковый номер которой заканчивается на такой же цифре, как и последняя цифра...»

«Методические рекомендации по оборудованию и использованию кабинетов информатики, классов с персональными электронно-вычислительными машинами или видеодисплейными терминалами в учебных заведениях системы общего среднего и среднего профессионального образования Разработано в Институте информатизации образования Российской академии образования. Научный руководитель разработки: И. В. Роберт, член-корреспондент РАО, доктор педагогических наук, профессор. Авторы: И. В. Роберт, член-корреспондент РАО,...»

«Частное образовательное учреждение высшего профессионального образования Омская юридическая академия МЕТОДИЧЕСКИЕ УКАЗАНИЯ по выполнению курсовой работы для студентов экономических специальностей и направлений подготовки Омск 2012 ББК 65р30 М 54 Методические указания по выполнению курсовой работы для студентов экономических специальностей и направлений подготовки / сост. М. В. Мясникова, С. М. Толкачев. – Омск : Омская юридическая академия, 2012. – 64 с. Рецензенты: М. Б. Ионина, доцент кафедры...»

«Региональная общественная организация ГОДОВОЙ ОТЧЕТ 2012 людей с инвалидностью ПЕРСПЕКТИВА Дорогие друзья! С огромным удовольствием представляю Вам отчет о деятельности Региональной общественной организации людей с инвалидностью Перспектива за 2012 год! Этот год стал очень значимым для Перспективы. Во-первых, в этом году исполнилось 15 лет нашей организации. Мы не устраивали пышных торжеств по этому поводу, но попытались подвести некие промежуточные итоги в рамках нескольких крупных...»

«1 БЮЛЛЕТЕНЬ НОВЫХ ПОСТУПЛЕНИЙ 16-31 МАРТА 2014г. В настоящий Бюллетень включены книги, поступившие в отделы Фундаментальной библиотеки с 16 по 31 марта 2014 г. Бюллетень составлен на основе записей Электронного каталога. Материал расположен в систематическом порядке по отраслям знания, внутри разделов – в алфавите авторов и заглавий. Записи включают полное библиографическое описание изданий, шифр книги и место хранения издания в сокращенном виде (список сокращений приводится в Бюллетене)....»

«А. Р. ГОРОНОВСКИЙ, В. Н. ЛОЙ, С. П. МОХОВ ЛЕСОТРАНСПОРТНЫЕ МАШИНЫ Учебно-методическое пособие по курсовому и дипломному проектированию для студентов специальностей 1-46 01 01 Лесоинженерное дело, 1-36 05 01 Машины и оборудование лесного комплекса специализации 1-36 05 01 01 Машины и механизмы лесной промышленности Минск БГТУ 2006 Учреждение образования БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНОЛОГИЧЕСКИЙ УНИВЕРСИТЕТ А. Р. ГОРОНОВСКИЙ, В. Н. ЛОЙ, С. П. МОХОВ ЛЕСОТРАНСПОРТНЫЕ МАШИНЫ Учебно-методическое...»

«Частное учреждение образования Минский институт управления УТВЕРЖДАЮ Ректор Минского института управления Н.В. Суша _ 2010 г. Регистрационный № УД-/р. МЕЖДУНАРОДНОЕ ЧАСТНОЕ ПРАВО Учебная программа для специальности: 1-24 01 02 Правоведение Факультет правоведения Кафедра гражданского и государственного права Курс – 5,6 Семестры – 10, 11 Лекции – Экзамен – 10 Практические (семинарские) Зачет – нет занятия – Лабораторные Курсовой проект (работа) – нет занятия – нет Всего аудиторных часов по...»

«НОУ ВПО САНКТ-ПЕТЕРБУРГСКИЙ ГУМАНИТАРНЫЙ УНИВЕРСИТЕТ ПРОФСОЮЗОВ САМАРСКИЙ ФИЛИАЛ ТЕОРЕТИЧЕСКИЕ ОСНОВЫ ОРГАНИЗАЦИИ ТУРИСТСКОЙ ОТРАСЛИ Методические указания по выполнению курсовых работ для студентов специальности Социально-культурная деятельность Самара 2009 Печатается по решению Учебно-методического совета Самарского филиала НОУ ВПО Санкт-Петербургский Гуманитарный университет профсоюзов УДК 379.85 Р е ц е н з е н т ы: Бурдина Г.Ю., кандидат исторических наук, доцент кафедры теории и практики...»

«Руденков И.А. ЭКОНОМИЧЕСКАЯ ПОЛИТИКА: учебное пособие. СОДЕРЖАНИЕ ВВЕДЕНИЕ Тема I: Предмет и теории экономической политики. 1) Экономическая теория и экономическая политика, предмет и области экономической политики; 2) Цели и задачи экономической политики; 3) Теория экономических порядков Вальтера Ойкена; 4) Концепция Я. Тинбергена и критика Р. Лукаса; 5) Школа общественного выбора Бьюкенена и Кеннета Эрроу; 6) Теория политического делового цикла. Тема II: Построение концепции экономической...»

«МИНИСТЕРСТВО ОБР АЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕР АЦИИ ФЕДЕР АЛЬНОЕ АГЕНТСТВО ПО ОБР АЗОВАНИЮ Негосударственное образовательное учреждение высшего профессионального образования Смоленский гуманитарный университет КаКафедра информационных технологий и безопасности Андреева А. В. Учебно-методическое пособие по дисциплине Мировые информационные ресурсы ФКТЭиД Смоленск А Составитель А.В. Андреева Учебно-методическое пособие по дисциплине Мировые информационные ресурсы. – Смоленск: Универсум, 2010....»

«МЕТОДИЧЕСКИЕ УКАЗАНИЯ для преподавателей к проведению практических занятий по клинической иммунологии со студентами медико-биологического факультета 4 курса ВолгГМУ в 2012/13 уч. г. 1. Тема занятия: Введение в клиническую иммунологию. Предмет и задачи клинической иммунологии. Возрастные особенности иммунитета. Принципы и методы оценки иммунного статуса. 2. Место проведения: учебная комната кафедры клинической фармакологии. 3. Продолжительность: 3 часа 4. Цель занятия: познакомить студентов с...»

«Министерство образования и науки РФ Сочинский государственный университет туризма и курортного дела Филиал Сочинского государственного университета туризма и курортного дела в г.Н.Новгород СБОРНИК МЕТОДИЧЕСКИХ МАТЕРИАЛОВ по учебным дисциплинам 1 курса для студентов заочной формы обучения специальность 080507 менеджмент организации Нижний Новгород 2010 ББК 65.290-2 С 23 Сборник методических материалов по учебным дисциплинам 1 курса для студентов заочной формы обучения; специальность 080507...»

«ОГЛАВЛЕНИЕ 1. ЦЕЛИ И ЗАДАЧИ ДИСЦИПЛИНЫ - ИСТОРИЯ МЕДИЦИНЫ, ЕЕ МЕСТО В СТРУКТУРЕ ОСНОВНОЙ ОБРАЗОВАТЕЛЬНОЙ ПРОГРАММЫ.3 2. КОМПЕТЕНЦИИ ОБУЧАЮЩЕГОСЯ, ФОРМИРУЕМЫЕ В РЕЗУЛЬТАТЕ ОСВОЕНИЯ ДИСЦИПЛИНЫ – ИСТОРИЯ МЕДИЦИНЫ. 3-4 3. ОБЪЕМ ДИСЦИПЛИНЫ И ВИДЫ УЧЕБНОЙ РАБОТЫ. 4-5 4. СОДЕРЖАНИЕ ДИСЦИПЛИНЫ.. 5-13 4.1. Лекционный курс...5- 7 4.2. Семинары...7-11 4.3. Самостоятельная внеаудиторная работа студентов. 11-13 5. МАТРИЦА РАЗДЕЛОВ УЧЕБНОЙ ДИСЦИПЛИНЫ И ФОРМИРУЕМЫХ В НИХ ОБЩЕКУЛЬТУРНЫХ И ПРОФЕССИОНАЛЬНЫХ...»

«Департамент образования администрации города Перми Муниципальное автономное общеобразовательное учреждение Гимназия №3 Утверждаю Принята Директор Гимназии № 3 методическом совете школы _ Новикова Т.В. сентября 2013 года сентября 2013 года м.п. Рабочая учебная программа по курсу ЛИТЕРАТУРНОЕ ЧТЕНИЕ в начальной школе 4 класс Программу составила Швецова О.Ю. учитель начальных классов Пермь, Пояснительная записка Данная рабочая учебная программа по курсу литературного чтения в начальной школе...»

«МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ УКРАИНЫ ЧЕРНИГОВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНОЛОГИЧЕСКИЙ УНИВЕРСИТЕТ Кафедра гуманитарных наук Секция экономической теории и предпринимательства по дисциплине: “Основы бизнеса” на тему: “Бизнес-план предприятия ОАО “ Житомирский молокозавод”” Выполнил: ст. гр. ОА-981 зачетная книжка № 980306 Проверил: Чернигов 2001 ЧЕРНИГОВСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНОЛОГИЧЕСКИЙ УНИВЕРСИТЕТ Кафедра гуманитарных наук _ Секция экономической теории и предпринимательства Дисциплина Основы...»

«МИНИСТЕРСТВО КУЛЬТУРЫ РОССИЙСКОЙ ФЕДЕРАЦИИ МОСКОВСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ КУЛЬТУРЫ И ИСКУССТВ МЕНЕДЖЕР ИНФОРМАЦИОННЫХ РЕСУРСОВ Учебно-методическое пособие Под общей редакцией профессора В.К. Клюева Рекомендовано Учебно-методическим объединением по образованию в области народной художественной культуры, социально-культурной деятельности и информационных ресурсов в качестве учебного пособия для студентов высших учебных заведений, обучающихся по специальности 071201 –...»






 
2014 www.av.disus.ru - «Бесплатная электронная библиотека - Авторефераты, Диссертации, Монографии, Программы»

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