КОНСПЕКТ ЛЕКЦИЙ междисциплинарного курса МДК.03.02. ИНСТРУМЕНТАЛЬНЫЕ СРЕДСТВА РАЗРАБОТКИ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ Специальность 09.02.03 Программирование в компьютерных системах Квалификация выпускника – Техник-программист Форма обучения – Очная 2016 г Содержание 1 Введение ............................................................................................................................ 3 1.1 Инструментальное программное обеспечение. Основные понятия и определения....................... 3 Базовые принципы построения CASE-средств ............................................................................ 4 Основные функциональные возможности CASE-средств .......................................................... 6 1.2 Назначение и виды инструментального ПО ....................................................................................... 9 1.3 Модели процесса разработки программного обеспечения ............................................................. 12 Контрольные вопросы .............................................................................................................................. 17 2 Разработка программного обеспечения ....................................................................... 19 2.1 Основные методы и средства эффективной разработки ПО .......................................................... 19 2.2 Основные подходы к интегрированию программных модулей ..................................................... 32 2.3 Модульная структура программных продуктов .............................................................................. 36 Контрольные вопросы .............................................................................................................................. 41 3 Методологии моделирования предметной области .................................................... 43 3.1 Основные принципы разработки надежного программного обеспечения .................................... 43 3.2 Функциональная методология IDEF0 ............................................................................................... 54 3.3 Методология DFD ............................................................................................................................... 63 3.4 Методология IDEF3 ............................................................................................................................ 65 Контрольные вопросы .............................................................................................................................. 73 4 Проектирование программного обеспечения при объектном подходе .................... 74 4.1 Разработка структуры программного обеспечения при объектном подходе. Основы унифицированного языка моделирования UML .................................................................................... 74 4.2 Экстремальное программирование ................................................................................................... 81 Контрольные вопросы .............................................................................................................................. 85 2 1 Введение 1.1 Инструментальное программное обеспечение. Основные понятия и определения Очевидно, что большие размеры и высокая сложность разрабатываемых ПС при ограничениях на бюджетные и временные затраты проекта могут привести к низкому качеству конечных программных продуктов и системы в целом. В этой связи в последнее время все большее внимание уделяется современным технологиям и инструментальным средствам, обеспечивающим автоматизацию процессов ЖЦ ПС (CASE-средствам). Использование таких инструментальных средств позволяет существенно сократить длительность и стоимость разработки систем и ПС при одновременном повышении качества процесса разработки и, как следствие, качества разработанных ПС. В истории развития CASE-средств обычно выделяется шесть периодов. Данные периоды различаются применяемой техникой и методами разработки ПС. Эти периоды используют в качестве инструментальных средств следующие средства. Период 1. Ассемблеры, анализаторы. Период 2. Компиляторы, интерпретаторы, трассировщики. Период 3. Символические отладчики, пакеты программ. Период 4. Системы анализа и управления исходными текстами. Период 5. Первое поколение CASE (CASE-I). Это CASE-средства, позволяющие выполнять поддержку начальных работ процесса разработки ПС и систем (анализ требований к системе, проектирование архитектуры системы, анализ требований к программным средствам, проектирование программной архитектуры, логическое проектирование баз данных). Адресованы непосредственно системным аналитикам, проектировщикам, специалистам в предметной области. Поддерживают графические модели, экранные редакторы, словари данных. Не предназначены для поддержки полного ЖЦ ПС. Период 6. Второе поколение CASE (CASE-II). Представляют собой, как правило, набор (линейку) инструментальных средств, каждое их которых предназначено для поддержки отдельных этапов процесса разработки или других процессов ЖЦ ПС. В совокупности обычно поддерживают практически полный ЖЦ ПС. Используют средства моделирования предметной области, графического представления требований, поддержки автоматической кодогенерации ПС. Содержат средства контроля и управления разработкой, интеграции системной информации, оценки качества результатов разработки. Поддерживают моделирование и прототипирование системы, тестирование, верификацию, анализ сгенерированных программ, генерацию документации по проекту. Ко второму поколению CASE-средств относятся, например, линейки Telelogic и AllFusion. CASE-технологии предлагают новый, основанный на автоматизации подход к концепции ЖЦ ПС. Современные варианты CASE-моделей ЖЦ, называемые обычно RAD-моделями. Наибольшие изменения в ЖЦ ПС при использовании CASE-технологий касаются первых этапов ЖЦ, связанных с анализом требований и проектированием. CASE-средства позволяют использовать визуальные среды разработки, средства моделирования и быстрого прототипирования разрабатываемой системы или ПС. Это позволяет на ранних этапах разработки оценить, насколько будущая система или программное средство устраивает заказчика и насколько она дружественна будущему пользователю. Таблица 1.1 содержит усредненные оценки трудозатрат по основным этапам разработки ПС при различных подходах к процессу разработки. Номерам строк в данной таблице соответствуют: 1 – традиционная разработка с использованием классических технологий; 2 – разработка с использованием современных структурных методологий проектирования; 3 – разработка с использованием CASE–технологий. Таблица 1.1 – Сравнительная оценка трудозатрат по этапам процесса разработки программных средств 3 № подхода 1 2 3 Анализ, % 20 30 40 Проектирование, % Кодирование, % 15 20 30 15 40 5 Тестирование, % 45 25 15 Из таблицы видно, что при традиционной разработке ПС основные усилия направлены на кодирование и тестирование, а при использовании CASE-технологий – на анализ и проектирование, поскольку CASE предполагают автоматическую кодогенерацию, автоматизированное тестирование и автоматический контроль проекта. Сопровождение кодов ПС заменяется сопровождением спецификаций проектирования. В результате данных факторов цена ошибок, вносимых в проект при разработке и сопровождении ПС и систем, существенно снижается. Резюме В истории развития CASE-средств обычно выделяется шесть периодов. При традиционной разработке ПС основные усилия направлены на кодирование и тестирование, при использовании CASE-технологий – на анализ и проектирование. Базовые принципы построения CASE-средств Большинство CASE-средств основано на парадигме метод – нотация –средство. Парадигма – это система изменяющихся форм некоторого понятия. В данном случае метод реализуется с помощью нотаций. Метод и нотации поддерживаются инструментальными средствами. Метод – это систематическая процедура или техника генерации описаний компонент ПС. Нотация – это система обозначений, предназначенная для описания структуры системы, элементов данных, этапов обработки; может включать графы, диаграммы, таблицы, схемы алгоритмов, формальные и естественные языки. Например, метод JSP реализуется с помощью нотации, базирующейся на применении четырех базовых конструкций данных. Современной нотацией методологии SADT является IDEF0. Средства – это инструментарий для поддержки методов, помогающий пользователям при создании и редактировании графического проекта в интерактивном режиме, способствующий организации проекта в виде иерархии уровней абстракции, выполняющий проверки соответствия компонентов. Например, средством, поддерживающим метод JSP, является SmartDraw. IDEF0 поддерживается средством BPwin. Фактически CASE-средство – это совокупность графически ориентированных инструментальных средств, поддерживающих процессы или отдельные этапы процессов ЖЦ ПС и систем. К CASE-средствам может быть отнесено любое программное средство, обеспечивающее автоматическую помощь при разработке ПС, их сопровождении или управлении проектом, базирующееся на следующих основополагающих принципах: 1. Графическая ориентация. В CASE-средствах используется мощная графика для описания и документирования систем или ПС и для улучшения интерфейса с пользователем. 2. Интеграция. CASE-средство обеспечивает легкость передачи данных между своими компонентами и другими средствами, входящими в состав линейки CASE-средств. Это позволяет поддерживать совокупность процессов ЖЦ ПС. 4 3. Локализация всей проектной информации в репозитории (компьютерном хранилище данных). Исполнителям проекта доступны соответствующие разделы репозитория в соответствии с их уровнем доступа. Это обеспечивает поддержку принципа коллективной работы. Информация из репозитория может использоваться для работ над текущим проектом, в том числе для автоматической кодогенерации ПС или систем, разработки следующих проектов, сбора статистики по выполненным ранее проектам организации. Помимо данных принципов в основе концептуального построения CASE-средств лежат следующие положения. 1. Человеческий фактор. Его учет позволяет привести процессы ЖЦ ПС и систем к легкой, удобной и экономичной форме. 2. Использование базовых программных средств, применяющихся в других приложениях (СУБД, компиляторы с различных языков программирования, отладчики, языки четвертого поколения 4GL и др.). 3. Автоматизированная или автоматическая кодогенерация. При автоматизированной кодогенерации выполняется частичная генерация кодов программного средства, остальные участки программируются вручную. При автоматической кодогенерации выполняется полная генерация кодов программного средства. Возможны различные виды генерации (например, генерация проектной документации, базы данных по информационной модели, кодов из разработанных спецификаций программного средства; автоматическая сборка модулей, хранящихся в репозитории). 4. Ограничение сложности. Такое ограничение позволяет поддерживать сложность компонентов разрабатываемого программного средства или системы на уровне, доступном для понимания, использования и модификации. 5. Доступность для различных категорий пользователей, в том числе заказчиков, специалистов в предметной области, системных аналитиков, проектировщиков, программистов, тестировщиков, инженеров по качеству, менеджеров проектов. CASE-средства содержат инструменты различного функционального назначения, поддерживающие различные этапы основных, вспомогательных и организационных процессов ЖЦ ПС и систем. 6. Рентабельность, обеспечивающая быструю окупаемость денежных средств, вложенных в приобретение CASE-средства, за счет сокращения сроков и стоимости проектов. 7. Сопровождаемость. CASE-средства обладают адаптации к изменяющимся требованиям и целям проекта. способностью Резюме CASE-средства представляют собой совокупность графически ориентированных инструментальных средств, поддерживающих ЖЦ ПС и систем. CASE-средства базируются на 5 принципах графической ориентации, интеграции и локализации всей проектной информации в репозитории. В основе построения CASE-средств лежат человеческий фактор, использование базовых ПС, автоматизированная или автоматическая кодогенерация, ограничение сложности, доступность для разных категорий пользователей, рентабельность, сопровождаемость. Основные функциональные возможности CASE-средств В состав CASE-средств входят четыре основных компонента: 1. Средства централизованного хранения всей информации о проекте (репозиторий). Предназначены для хранения информации о разрабатываемом программном средстве или системе в течение всего ЖЦ разработки. 2. Средства ввода. Служат для ввода данных в репозиторий, организации взаимодействия участников проекта с CASE-средством. Должны поддерживать различные методологии анализа, проектирования, тестирования, контроля. Предназначены для использования в течение ЖЦ программного средства или системы различными категориями участников проекта (системными аналитиками, проектировщиками, программистами, тестировщиками, менеджерами, специалистами по качеству и т.д.). 3. Средства анализа и разработки. Предназначены для анализа различных видов графических и текстовых описаний и их преобразований в процессе разработки. 4. Средства вывода. Служат для кодогенерации, создания различного вида документов, управления проектом. Все компоненты CASE-средств в совокупности обладают следующими функциональными возможностями: поддержка графических моделей; контроль ошибок; поддержка репозитория; поддержка основных, вспомогательных и организационных процессов ЖЦ ПС. Поддержка графических моделей В CASE-средствах разрабатываемые ПС представляются схематически. На разных уровнях проектирования могут использоваться различные виды и нотации графического представления ПС. Обычно применяются диаграммы различных типов, в том числе иерархии требований, диаграммы функционального моделирования (например IDEF0, DFD), диаграммы информационного моделирования (например IDEF1X), структурограммы , диаграммы Джексона, диаграммы Варнье – Орра, UML-диаграммы и т.п. Разработка диаграмм осуществляется с помощью специальных графических редакторов, основными функциями которых являются создание и редактирование иерархически связанных диаграмм, их объектов и связей между объектами, а также автоматический контроль ошибок. Контроль ошибок В CASE- средствах , как правило, реализуются следующие типы контроля: 6 1. Контроль синтаксиса диаграмм и типов их элементов. Например, при IDEF0-моделировании контролируется максимальное и минимальное количество функциональных блоков на диаграммах, наличие дуги управления и выходной дуги для любого функционального блока и т.п. 2. Контроль полноты и корректности диаграмм. При данном типе контроля выполняется проверка наличия имен у всех элементов диаграмм, проверка наличия необходимых описаний в репозитории и др. 3. Контроль декомпозиции функций. При данном типе контроля выполняется оценка декомпозиции на основе различных метрик. Например, может быть оценена эффективность и корректность декомпозиции с точки зрения связности и сцепления модулей. 4. Сквозной контроль диаграмм одного или различных типов на предмет их взаимной корректности. Например, при IDEF0-моделировании контролируется соответствие граничных дуг родительского блока с внешними дугами дочерней диаграммы. При разработке IDEF0- и IDEF1Х-моделей предметной области выполняется контроль их взаимной корректности и непротиворечивости. Поддержка репозитория Основными функциями репозитория являются хранение, обновление, анализ, визуализация всей информации по проекту и организация доступа к ней. Репозиторий обычно хранит более 100 типов объектов (например, диаграммы, определения экранов и меню, проекты отчетов, описания данных, модели данных, модели обработки, исходные коды, элементы данных). Каждый информационный объект, хранящийся в репозитории, описывается совокупностью своих свойств, например, идентификатор, тип, текстовое описание, компоненты, область значений, связи с другими объектами, времена создания и последнего обновления объекта, автор и т.п. Репозиторий является базой для автоматической генерации документации по проекту. Основными типами отчетов являются: отчеты по содержимому – включают информацию по потокам данных и их компонентов; списки функциональных блоков диаграмм и их входных и выходных потоков; списки всех информационных объектов и их атрибутов; историю изменений объектов; описания модулей и интерфейсов между ними; планы тестирования модулей и т.п.; отчеты по перекрестным ссылкам – содержат информацию по связям всех вызывающих и вызываемых модулей; списки объектов репозитория, к которым имеет доступ конкретный исполнитель проекта; информацию по связям между диаграммами и конкретными данными; маршруты движения данных от входа к выходу; отчеты по результатам анализа – включают данные по взаимной корректности диаграмм, списки неопределенных информационных объектов, списки неполных диаграмм, данные по результатам анализа структуры проекта и т.п.; отчеты по декомпозиции объектов – включают совокупности объектов, входящих в каждый объект, а также объекты, в состав которых входит каждый объект. 7 Поддержка процессов жизненного цикла программных средств и систем Основой поддержки процесса разработки являются следующие свойства современных CASEсредств. 1. Покрытие всего жизненного цикла систем или программных средств. Как отмечалось, современные CASE-средства поддерживают практически полный ЖЦ ПС. Однако первоочередное внимание уделяется начальным работам процесса разработки – анализу требований к системе, проектированию системной архитектуры, анализу требований к программным средствам и проектированию программной архитектуры. Грамотная разработка требований к системе и ПС является основой всего проекта, их полнота и корректность определяют уровень соответствия результатов разработки требованиям заказчика. 2. Поддержка прототипирования. Большинство моделей ЖЦ, предназначенных для разработки сложных или критичных продуктов, базируются на применении прототипирования. Это касается в первую очередь моделей, поддерживающих инкрементную и эволюционную стратегии разработки. Прототипирование применяется на ранних этапах ЖЦ и позволяет уточнять требования к системе или программному средству, а также прогнозировать поведение разрабатываемого продукта. 3. Поддержка современных методологий разработки систем или программных средств. Современные линейки CASE-средств поддерживают, как правило, различные методологии, предназначенные для использования на различных этапах процесса разработки. При этом выполняется графическая поддержка построения диаграмм различных типов, контроль корректности использования шагов проектирования и подготовка документации. 4. Автоматическая кодогенерация. Кодогенерация позволяет построить автоматически до 90 % исходных кодов на языках высокого уровня. Различными CASE-средствами поддерживаются практически все известные языки программирования. Средства кодогенерации можно подразделить на два вида: средства генерации управляющей структуры продукта; данные средства выполняют автоматическое построение логической структуры программного средства, кодов для базы данных, файлов, экранов, отчетов. Остальные фрагменты программного средства кодируются вручную; средства генерации полного продукта; данные средства позволяют на основе разработанных спецификаций или моделей генерировать полные коды программного средства, пользовательскую и программную документацию к нему. Резюме В состав CASE-средств входят средства централизованного хранения информации о проекте (репозиторий), средства ввода, средства анализа и разработки, средства вывода. Все 8 компоненты CASE-средств в совокупности поддерживают графические модели, репозиторий, процесс разработки и ряд вспомогательных и организационных процессов, выполняют контроль ошибок. 1.2 Назначение и виды инструментального ПО Все CASE-средства подразделяются на типы, категории и уровни. Классификация по типам Данная классификация отражает функциональное назначение CASE-средства в ЖЦ ПС и систем. 1. Анализ и проектирование Средства этого типа используются для поддержки начальных этапов процесса разработки: анализа предметной области, разработки требований к системе, проектирования системной архитектуры, разработки требований к программным средствам, проектирования программной архитектуры, технического проектирования программных средств. Средства данного типа поддерживают известные методологии анализа и проектирования. На выходе генерируются спецификации системы, ее компонентов и интерфейсов, связывающих эти компоненты, архитектура системы, архитектура программного средства, технический проект программного средства, включая алгоритмы и определения структур данных. К средствам данного типа можно отнести, например, AllFusion Process Modeler (BPwin), CASE.Аналитик, Design/IDEF, Telelogic DOORS, Telelogic Modeler, Telelogic TAU, Telelogic Rhapsody, Telelogic Statemate 2. Проектирование баз данных и файлов Средства этого типа обеспечивают логическое моделирование данных, автоматическое преобразование моделей данных в третью нормальную форму, автоматическую генерацию схем баз данных и описаний форматов файлов на уровне программного кода. К средствам этого типа можно отнести, например, AllFusion Data Modeler (ERwin), CA ERwin Data Model Validator (ранее ERwin Examiner), S-Designor, Silverrun, Designer2000, Telelogic TAU, Telelogic Rhapsody. 3. Программирование и тестирование Средства этого типа поддерживают седьмую работу процесса разработки (программирование и тестирование). Данные средства выполняют автоматическую кодогенерацию ПС на основе спецификаций или моделей. Содержат графические редакторы, средства поддержки работы с репозиторием, генераторы и анализаторы кодов, генераторы тестов, анализаторы покрытия тестами, отладчики. К средствам данного типа можно отнести, например, TAU/Developer, TAU/Tester, Logiscope Audit, Logiscope RuleChecker, Logiscope TestChecker, Logiscope Reviewer, Rhapsody Developer. 4. Сопровождение и реинженерия Общей целью средств этого типа является поддержка корректировки, изменения, преобразования, реинженерия существующей системы, поддержка документации по проекту. К данным средствам относятся средства документирования, анализаторы программ, средства управления изменениями и конфигурацией ПС и систем, средства реструктурирования и реинженерии (реинженерия, реинженеринг – reverse engineering – обратное проектирование, например, построение спецификаций или моделей по исходным текстам программ), средства обеспечения мобильности, позволяющие перенести разработанную систему или программные средства в новое операционное или аппаратное окружение. Средства реинженерии включают: статические анализаторы для генерирования схем программного средства из его кодов и оценки влияния модификаций; 9 динамические анализаторы, включающие трансляторы со встроенными отладочными возможностями; документаторы, автоматически изменении кода программного средства; обновляющие документацию при редакторы кодов, автоматически изменяющие при редактировании кодов предшествующие ему структуры, в том числе и спецификации требований; средства доступа к спецификациям, позволяющие модификацию и генерацию модифицированного кода; выполнять их средства реверсной инженерии, транслирующие коды в спецификации или модели. К средствам данного типа можно отнести, например, Telelogic DocExpress, Telelogic Synergy, Telelogic Change, средства линейки AllFusion Change Management Suite. Следует отметить, что ряд CASE-средств других типов содержат в своем составе средства реинженерии. Это касается, например, CASE-средств AllFu-sion Data Modeler, Telelogic Rhapsody. 5. Окружение К средствам данного типа относятся средства поддержки интеграции CASE-средств и данных. К данному типу можно отнести, например, Telelogic Rhapsody Gateway, Telelogic Rhapsody Interface Pack, AllFusion Data Profiler, AllFusion Model Manager, AllFusion Model Navigator. 6. Управление проектом К средствам данного типа относятся средства поддержки процесса управления ЖЦ ПС и систем. Их функциями являются планирование, контроль, руководство, организация взаимодействия и т.п. К средствам данного типа можно отнести, например, Telelogic Focal Point, Telelogic Dashboard, AllFusion Process Management Suite, ADvisor. Резюме Классификация CASE-средств по типам отражает функциональное назначение CASE-средства в ЖЦ ПС. Выделяют типы CASE-средств, ориентированные на следующие этапы процесса разработки и другие процессы ЖЦ: анализ и проектирование, проектирование баз данных и файлов, программирование и тестирование, сопровождение и реинженерия, окружение, управление проектом. Классификация по категориям Данная классификация отражает уровень интегрированности CASE-средств по выполняемым функциям. 1. Категория Tool (tool – рабочий инструмент) Включает средства самого низкого уровня интегрированности. В данную категорию средств входят инструментальные средства, решающие небольшую автономную задачу при разработке программного средства или системы. Обычно средства данной категории являются компонентами CASE-средств более высокого уровня интегрированности. 2. Категория ToolКit (toolкit – набор инструментов, пакет разработчика) Включает CASEсредства среднего уровня интегрированности. Средства данной категории используют репозиторий для всей информации о проекте и ориентированы обычно на поддержку одного этапа или одной работы процесса разработки или на поддержку одного из вспомогательных или организационных процессов ЖЦ ПС или систем. CASE-средства данной категории 10 представляют собой интегрированную совокупность инструментальных средств, имеющих как правило общую функциональную ориентацию. К CASE-средствам данной категории может быть отнесено, например, большинство CASEсредств из линеек Telelogic и AllFusion при их изолированном использовании. 3. Категория Workbench (workbench – рабочее место). CASE-средства данной категории обладают самой высокой степенью интеграции. Они представляют собой интегрированную совокупность инструментальных средств, поддерживающих практически весь процесс разработки и ряд вспомогательных и организационных процессов ЖЦ ПС и систем. Используют репозиторий для хранения информации по проекту, поддерживают организацию коллективной работы над проектом. Обычно к категории Workbench относятся линейки CASE-средств при их интегральном использовании. Примерами являются линейки Telelogic и AllFusion. Данные линейки CASEсредств поддерживает практически полностью процесс разработки ПС и систем, процессы сопровождения, документирования, управления конфигурацией, частично процессы обеспечения качества, верификации, аттестации. Таким образом, линейки Telelogic и AllFusion поддерживают практически весь ЖЦ ПС и систем. Резюме Классификация по категориям отражает уровень интегрированности CASE-средств по выполняемым функциям. Различают категории Tool, ToolКit, Workbench. Классификация по уровням Данная классификация связана с областью действия CASE-средств в ЖЦ ПС, систем и организаций. 1. Верхние (Upper) CASE-средства CASE-средства данного уровня называют средствами компьютерного планирования. Их основной целью является помощь руководителям организаций, предприятий и конкретных проектов в определении политики организации и создании планов проекта. CASE-средства данного уровня позволяют строить модель предметной области, проводить анализ различных сценариев (существующего, наилучших, наихудших), накапливать информацию для принятия оптимальных решений. Таким образом, применительно к ЖЦ ПС и систем данные средства поддерживают процесс заказа и первую работу процесса разработки (подготовка процесса разработки). Графические средства данного уровня используются как формализованный язык общения между заказчиком (пользователем) и разработчиком требований. К средствам данного уровня можно отнести, например, Telelogic System Architect, Telelogic Focal Point, Telelogic Dashboard, средства линейки AllFusion Modeling Suite. 2. Средние (Middle) CASE-средства CASE-средства данного уровня поддерживают начальные этапы процесса разработки (анализ предметной области, разработка требований к системе, проектирование системной архитектуры, разработка требований к программным средствам, проектирование программной архитектуры). При этом встроенные графические средства используются как формализованный язык общения между заказчиком (пользователем) и разработчиком спецификаций требований. Обычно данные средства обладают возможностями накопления и хранения информации по проекту. Это позволяет использовать накопленные данные как в текущем, так и в других проектах. Например, с помощью накопленной информации могут оцениваться продукты текущего проекта. При этом аналогичная информация предыдущих проектов используется в качестве базовой для оценки. CASE-средства данного уровня зачастую поддерживают прототипирование и автоматическое документирование. К CASE-средствам данного уровня можно отнести, например, линейку AllFusion Modeling Suite, средства Telelogic DOORS, Telelogic Modeler, Telelogic Tau, Telelogic Rhapsody, Telelogic Statemate, Telelogic DocExpress. 11 3. Нижние (Lower) CASE-средства CASE-средства данного уровня поддерживают вторую половину работ процесса разработки ПС. Содержат графические средства, исключающие необходимость разработки физических мини – спецификаций для программных модулей. Спецификации представляются обычно в виде моделей, которые непосредственно преобразуются в программные коды разрабатываемого программного средства или системы. Автоматически генерируется до 90 % кодов. Входной информацией для кодогенераторов являются спецификации, разработанные как в CASEсредствах данного уровня, так и в CASE-средствах среднего уровня. CASE-средства нижнего уровня, как правило, поддерживают также прототипирование, тестирование, управление конфигурацией, генерацию документации, облегчают модификацию и сопровождение ПС или систем. К CASE-средствам данного уровня можно отнести AllFusion Data Modeler, Telelogic Rhapsody, Telelogic Tau, Telelogic Statemate, Telelogic TAU Logiscope, Telelogic Change, Telelogic Synergy, Telelogic DocExpress. Следует отметить, что в состав CASE-средств среднего и высокого уровней интегрированности обычно входят инструментальные средства, относящиеся к нескольким уровням. Линейки CASE-средств, предназначенные для поддержки всего ЖЦ ПС и систем, включают в свой состав средства всех трех уровней. Резюме Классификация по уровням связана с областью действия CASE-средств в ЖЦ ПС и систем. Различают верхние, средние и нижние CASE-средства. Линейки CASE-средств включают в свой состав средства всех трех уровней. 1.3 Модели процесса разработки программного обеспечения Исторически в ходе развития теории проектирования программного обеспечения и по мере его усложнения утвердились четыре основные модели ЖЦ. Первой по времени появления и самой распространенной явилась каскадная модель (рисунок 1.1). 12 Рисунок 1.1 – Каскадная модель жизненного цикла ПО Каскадная модель характеризуется следующими основными особенностями: последовательным выполнением входящих в ее состав этапов; окончанием каждого предыдущего этапа до начала последующего; отсутствием временного перекрытия этапов (последующий этап не начнется, пока не завершится предыдущий); отсутствием (или определенным ограничением) возврата к предыдущим этапам; наличием результата только в конце разработки. Выявление и устранение ошибок в каскадной модели производится только на стадии тестирования, которая может растянуться во времени или вообще никогда не завершиться. Следующей стадией развития теории проектирования ПО стала итерационная модель ЖЦ, или так называемая поэтапная модель с промежуточным контролем (рисунок. 1.2). Основной ее особенностью является наличие обратных связей между этапами, вследствие этого появляется возможность проведения проверок и корректировок проектируемой ИС на каждой стадии разработки. В результате трудоемкость отладки по сравнению с каскадной моделью существенно снижается. Итерационность модели проявляется в обработке ошибок, выявленных промежуточным контролем. Если на каком-либо этапе в ходе промежуточной проверки обнаружена ошибка, допущенная на более ранней стадии разработки, необходимо повторить весь цикл работ этой стадии. При этом анализируются причины ошибки и корректируются в случае необходимости исходные данные этапа или его содержание (последовательность действий). 13 Рисунок 1.2 - Итерационная модель жизненного цикла ПО К сожалению, в процессе разработки системы могут измениться начальные требования, и в этом случае итерационная модель может оказаться неэффективной. Рисунок 1.3 – Спиральная модель жизненного цикла ПО Третья модель ЖЦ ПО — спиральная (spiral) модель (рисунок 1.3) — поддерживает итерации поэтапной модели, но особое внимание уделяется начальным этапам проектирования: анализу требований, проектированию спецификаций, предварительному проектированию и детальному проектированию. Каждый виток спирали соответствует поэтапной модели создания фрагмента или версии ПО, уточняются цели и требования к про грамм ному обеспечению, оценивается качество разработанного фрагмента или версии и планируются работы следующей стадии 14 разработки (витка). Таким образом, углубляются и конкретизируются все детали проектируемого ПО, в результате получается продукт, который удовлетворяет всем требованиям заказчика. Rational Objectory Process — модель жизненного цикла (методология объектноориентированного программирования) Известно, что объектно-ориентированное проектирование программного обеспечения стало результатом появления объектно-ориентированного программирования (ООП), т. е. применение новой методологии, как псегда1, началось с этапа кодирования. Ранние стадии описания предметной области и разработки архитектуры системы не поддерживались, первые варианты использования объектно-ориентированной методологии в большей степени являлись чистым повторением принципов ООП. Такие вопросы» как декомпозиция предметной области, спецификация требований, интерфейс пользователя, не рассматривались, однако успехи объектно-ориентированного программирования заставили распространить новую технологию на весь жизненный цикл ПО. В результате все преимущества подхода применяются не только в процессе кодирования, но и на более ранних этапах. Таким образом, были определены основные компоненты методологии: • модель жизненного цикла; • действия; • нотация языка. Жизненный цикл UML (Rational Objectory Process) Фирма Rational Software, разработавшая язык UML (Unified Modeling Language — унифицированный язык моделирования), предложила также и свою модель ЖЦ, которая называется Rational Objcctory Process (ROP). Означенная технология прямого перс-вода не имеет, так как rational в данном случае употребляется в значении «рациональный» и как название фирмы одновременно, во-вторых, слова objectory в английском языке не существует, его лингвообразованис аналогично слову repository (накопитель). Перечислим основные свойства ROP-технологии. Rational Objectory Process — итеративный процесс, в течение которого происходит последовательное уточнение результатов. Rational Objectory Process направлен именно на создание моделей, а не на разработку какихлибо других элементов проекта (например, текстовых документов). Действия Rational Objectory Process определяются в первую очередь блоками использования (use case) (рисунок 1.4). 15 Рисунок 1.4 – Молель жизненного цикла UML Rational Objectory Process разбит на циклы, каждый из которых, в свою очередь, состоит из четырех фаз: • начальная стадия (Inception); • разработка (Elaboration); • конструирование (Construction); • ввод в эксплуатацию (Transition). Результатом работы каждого такого цикла является своя версия программной системы. Каждая стадия завершается в четко определенной контрольной точке (milestone). В этот момент времени должны достигаться важные результаты и приниматься критически важные решения о дальнейшей разработке. Начальная стадия может принимать множество разных форм. Для крупных проектов — это всестороннее изучение всех возможностей реализации на протяжении нескольких месяцев. Здесь же вырабатывается бизнес-план проекта, определяется его стоимость, примерный доход, а также ограничения ресурсов — иными словами, выполняется некоторый начальный анализ оценки проекта. Окончанием начального этапа могут служить следующие результаты: начальный проектный словарь терминов; общее описание системы — основные требования к проекту, его характеристики и ограничения; начальная модель вариантов использования; начальный бизнес-план; план проекта, отражающий стадии и итерации; один или несколько прототипов. 16 На стадии разработки выявляются более детальные требования к системе, выполняется высокоуровневый анализ предметной области и проектирование базовой архитектуры системы, создается план конструирования и устраняются наиболее рискованные элементы проекта. Самым важным результатом стадии разработки является описание базовой архитектуры будущей системы. Эта архитектура включает: • модель предметной области, которая служит отправным пунктом для формирования основных абстракций предметной области; • технологическую платформу, определяющую основные элементы технологии реализации системы и их взаимодействие. Стадия разработки занимает примерно пятую часть времени создания проекта, результатом которой являются: • оценка времени реализации каждого варианта использования; • идентификация всех наиболее серьезных рисков и возможности их ликвидации. Сущность стадии конструирования заключается в определении последовательности итераций конструирования и вариантов использования, реализуемых на каждой итерации, которые являются одновременно инкрементными и повторяющимися. При этом необходимо отмстить следующее: • итерации являются инкрементными в соответствии с выполняемой функцией. Каждая итерация добавляет очередные конструкции к вариантам использования, реализованным во время предыдущих итераций; • итерации являются повторяющимися по отношению к разрабатываемому коду. На каждой итерации некоторая часть существующего кода переписывается с целью сделать его более гибким. Результатом стадии конструирования является продукт, готовый к передаче пользователям и содержащий, как правило, руководство пользователей и готовый к интеграции на требуемых платформах. Назначением стадии ввода в эксплуатацию является передача готового продукта в полное распоряжение конечных пользователей. Данная стадия включает: • бета-тестирование, позволяющее убедиться, что новая система соответствует ожиданиям пользователей; • параллельное функционирование с системой, которая подлежит постепенной замене; существующей (legacy) • оптимизацию производительности; • обучение пользователей и специалистов службы сопровождения. Контрольные вопросы 1. Что такое жизненный цикл программного обеспечение? 2. Перечислите основные модели процесса разработки программного обеспечения? 17 3. Каковы основные свойства каскадной (итерационной) модели жизненного цикла? 4. Из каких этапов состоит модель жизненного цикла UML? 18 2 Разработка программного обеспечения 2.1 Основные методы и средства эффективной разработки ПО Существуют два стиля проектирования: эволюционное и предварительное проектирование. Методология Extreme Programming (XP) бросила вызов многим устоявшимся представлениям о разработке программного обеспечения. Пожалуй, наиболее противоречивой идеей является отказ от предварительного проектирования в пользу более эволюционного Подхода. Противники ХР считают, что это возврат к разработкам типа «code and fix» («пишем и правим»). Для приверженцев же новой методологии это отказ от техник проектирования (например, UML), их принципов. Незачем беспокоиться о проектировании, считают они. Достаточно внимательно «вслушиваться» в свой код, и проектирование образуется само собой. В большинстве случаев эволюционное проектирование — это нечто ужасное. В конце концов, все равно вместо дизайна системы вы получаете просто набор из специфических решений, каждое из которых затрудняет дальнейшие изменения в программном коде. Часто это вообще нельзя считать дизайном (и, уж конечно, такой дизайн никак нельзя назвать хорошим). Как говорит Кент, дизайн существует для того, чтобы дать возможность оперативно вносить в систему любые изменения. Если дизайн плох, то такая возможность исчезает. В результате вы будете иметь дело с энтропией программного продукта, и со временем и без того плохой дизайн системы станет еще хуже. Теперь вам будет не только сложнее вносить в систему изменения, но и отыскивать и исправлять ошибки, которые начинают множиться с катастрофической быстротой. Все это — кошмар разработок в стиле «code and fix», когда с течением времени исправление ошибок обходится все дороже и дороже. Предварительное проектирование — полная противоположность эволюционному. При разработке ПО проектировщики заранее продумывают все основные вопросы. При этом они не пишут программный код, поскольку не создают программный продукт, а только разрабатывают его дизайн. В своей работе они могут использовать такие техники, как UML, что позволяет им абстрагироваться от некоторых подробностей разработок, относящихся непосредственно к программированию. Как только проектный план готов, его можно передавать в другой отдел (или даже в другую компанию), где будут вестись работы по непосредственному созданию системы. Поскольку проектировщики работают на некотором уровне абстракции, им удается избежать принятия ряда тактических решений, ведущих к энтропии программного продукта. Программисты же могут руководствоваться проектным планом и (если они ему следуют) создавать качественно выстроенную систему. Такой подход к разработке ПО не нов — им активно пользуется множество людей начиная с 1970-х годов. По многим показателям он гораздо лучше, чем эволюционное проектирование в стиле «code and fix», однако и у него есть существенные недостатки. Один из главных недостатков заключается в том, что невозможно заранее продумать все вопросы, с которыми придется столкнуться во время кодирования системы. Таким образом, в ходе работ непременно возникнет ситуация, когда у программистов появятся вопросы относительно спроектированного дизайна. А что, если проектировщики, закончив свою часть работы, уже переключились на другой проект? Тогда программисты начинают самостоятельно решать сложившуюся проблему, отступая от уже принятых проектных решений и внося при этом в Программный продукт долю энтропии. И даже если проектировщик еще работает над проектом и может помочь, все равно ему потребуется довольно много времени, чтобы выяснить ситуацию, внести изменения в диаграммы и уже затем менять код. Л при разработке, как правило, вопрос времени всегда стоит остро. Отсюда энтропия (опять-таки). Кроме того, существует еще и проблема культур. Проектировщиками становится благодаря высокому мастерству и большому опыту в программировании. Однако, став проектировщиком, программист настолько поглощается новой работой что просто не имеет физической возможности заниматься па-писанием программного кода. При этом инструментарий и материалы программных разработок постоянно меняются. А когда вы перестаете сами писать 19 код, вы не только теряете возможность отслеживать новшества в этой области. Вы теряете уважение тех, кто продолжает заниматься написанием программного кода. Однако такие проблемы все же можно как-то урегулировать. Может быть, можно что-то сделать с напряженностью в отношениях между людьми. Может быть, можно найти таких проектировщиков, которые могли бы разбираться в большинстве вопросов, и такой дисциплинированный процесс разработки, который позволял бы вносить изменения в диаграммы. Однако остается еще одна проблема — изменяющиеся требования. Именно изменяющиеся требования являются проблемой номер один. Бороться с изменяющимися требованиями можно по-разному. Один из возможных путей — делать дизайн достаточно гибким, чтобы при изменениях в требованиях его можно было легко менять. Однако для этого требуется заранее знать, какого типа изменения следует ожидать. Да, при проектировании системы можно попытаться угадать те области, в которых наиболее вероятны изменения, и учесть их в дизайне. В этом случае вы, действительно, облегчите себе работу с ожидаемыми изменениями в требованиях, но ничуть не облегчите (а возможно, только ухудшите) ситуацию с изменениями неожиданными. Кроме того, чтобы заранее определить тс области, в которых наиболее вероятны изменения, вы должны прекрасно понимать требования, что, по наблюдениям, очень непросто. Впрочем, не все проблемы с изменениями в требованиях возникают из-за их непонимания. Множество людей напряженно работают над разработкой технических требований к системе в надежде, что это убережет их от дальнейших поправок при проектировании. Но и так вы далеко не всегда сможете решить проблему. Многие изменения в требованиях диктуются изменениями в экономике в том виде бизнеса, для которого предназначается система. Такие изменения предугадать невозможно, сколько бы вы ни сидели над разработкой требований. Проектирование программного обеспечения при структурном подходе При проектировании сложного программного обеспечения прежде всего необходимо определить структурные компоненты и связи между ними. Полученная в результате структура ПО должна быть представлена в виде структурной или функциональной схем и спецификаций ее компонентов. Структурная схема разрабатываемого программного обеспечении Структурной называют схему, отражающую состав и взаимодействие по управлению частей разрабатываемого программного обеспечения. Структурная схема определяется архитектурой разрабатываемого ПО. Разработку структурной схемы программы обычно выполняют методом пошаговой детализации. Структурные схемы пакетов программ разрабатывают для каждой программы пакета по отдельности, поскольку организация программ в пакеты не предусматривает передачи управления между ними. Компонентами структурной схемы программной системы или программного комплекса могут служить программы, подсистемы, базы данных, библиотеки ресурсов и т. п. Пример структурной схемы программного комплекса для решения математических задач изображен на рисунок 2.1. Как правило, для программных систем разрабатывается функциональная схема, которая лает более полное представление о проектируемом программном обеспечении с точки зрения взаимодействия его компонентов между собой и с внешней средой. 20 Рисунок 2.1 - Пример структурной схемы программного комплекса Функциональная схема Функциональная схема (ГОСТ 19.701—90) — это схема взаимодействия компонентов программного обеспечения с описанием информационных потоков, состава данных в потоках и указанием используемых файлов и устройств. Для изображения функциональных схем используют специальные обозначения, установленные стандартом (таблица 2.1). Таблица 2.1 - Обозначения элементов функциональных схем Функциональные схемы более информативны, чем структурные. На рисунке 2.2 приведена функциональная схема программно го комплекса, реализующего различные методы сортировки массивов. 21 Рисунок 2.2 - пример функциональной схемы программного комплекса Метод пошаговой детализации при составлении алгоритмов Метод пошаговой детализации реализует нисходящий подход к программированию и предполагает пошаговую разработку алгоритма. Можно выделить следующие этапы: 1. Создается описание программы в целом. Определяются основные логические шаги, требуемые для решения задачи, даже могут отражать различные физические способы решения или могут быть удобными групповыми именами для тех действий, выполнение который представляется довольно смутно. Последовательности шагов, требуемых для решения задачи, записываются на обычном языке или на псевдокоде. 2. В общих терминах детализируется описание шагов, введенных на этапе 1. В детализированное описание может входить обозначение циклических структур, в то время как действия внутри циклов могут по-прежнему оставаться неясными. Таким образом, выполняются только общие эскизы сложных действий. 3. На этом и последующих уровнях в виде последовательных итераций производятся те же действия, что описаны на этапе 2. При каждой новой итерации уточняются детали, оставшиеся неясными после предыдущих итераций, и создаются более определенные описания. По мере выполнения итераций неопределенные детали становятся все проще и проще, так что на каком-то этапе могут быть полностью описаны. 4. Разработка завершена: в модульном виде получено описание требуемой программы. Перевод этого описания в программу на конкретном языке программирования должен быть достаточно простой задачей. При решении реальной задачи может потребоваться написание на псевдокоде многих уровней, чтобы довести все модули до такого состояния, при котором они окажутся готовыми для программирования. 22 Структурные карты Константайна Методика структурных карт используется на этапе проектирования ПО для того, чтобы продемонстрировать, каким образoм программный продукт выполняет системные требования. При этом наиболее часто применяются две техники: структурные карты Константайна (Constantine), предназначенные для описания отношений между модулями, и структурные карты Джексона (Jackson), предназначенные для описания внутренней структуры модулей. Структуру программной системы составляют модули, которые в любом языке программирования имеют следующие общие свойства: модуль имеет имя, по которому к нему можно обращаться как к единому фрагменту; модуль состоит из множества операторов языка программирования, записанных последовательно; модуль может принимать и/или передавать данные как параметры в вызывающей последовательности или связывать данные через фиксированные ячейки или общие области. Структурные карты Константайна представляют собой модель отношений между модулями программы. Узлы структурных карт соответствуют модулям и областям данных, потоки изображают межмодульные связи. Нa диаграмме специальными узлами изображаются циклические и условные вызовы модулей, а потоки проходят через эти специальные узлы. Потоки, изображающие межмодульные связи по данным и управлению, также изображаются на диаграмме специальными узлами, а стрелками указываются направления потоков. На рисунке 2.3 приведены основные компоненты структурных карт Константайна. Рисунок 2.3 - Элементы структурных карт: а — модуль; б — вызов модуля; в — связь по данным; г — связь по управлению Модуль является базовым элементом структурной карты. Различают следующие типы модулей (рисунок 2.4): модуль (рисунок 2.4, а); подсистема — детализированный модуль или программа. Может использоваться повторно любое число раз (рисунок 2.4, б); библиотека — совокупность подпрограмм, размещенных в модуле отдельно отданной системы (рисунок 2.4, в); область данных — описывает модули, содержащие исключительно области глобальных/распределенных данных (рисунок 2.4, г). 23 Рисунок 2.4 – Типы модулей Отдельные части программной системы (программы, подпрограммы) могут вызываться последовательно, параллельно или как сопрограммы (рисунок 2.5), Рисунок 2.5 – Типы вызовов модулей Для моделирования условных и циклических вызовов применяются следующие узлы (рисунок 2.6): условный узел применяется для моделирования конструкций IF-THEN-ELSE (на диаграмме из узла выходят два потока) и IF-THEN (из узла выходит один поток). Условный узел изображается в виде ромба, потоки — альтернативные вызовы — изображаются выходящими из него; итерационный узел используется для того, чтобы показать, что вызываемый модуль выполняется в цикле. Он изображается полуокружностью со стрелкой с выходящими из него потоками. Рисунок 2.6- Условные и циклические вызовы модулей: а - циклический; б — условный; в — однократный Если необходимо показать, что подчиненный модуль вызывается однократно, это осуществляется указанием цифры «1» рядом со стрелкой, обозначающей вызов модулянаследника. Связи по данным и управлению между модулями (передаваемые как параметры) обозначают стрелками, параллельными дуге вызова, которые показывают направления связей (рисунок 2.7). 24 Рисунок 2.7 - Связи а — по данным; б- по управлению Пример. Разработать структурную карту Константайна для задачи сортировки одномерного массива с помощью алгоритмов Пузырька, прямого выбора и Шелла. Программа состоит из модулей Меню, Методов сортировки и Вывода результата. Пользователь выбирает нужный метод, вводит массив и получает в результате отсортированный массив. Рисунок 2.8 – Пример структурной карты Константайна Результат приведен на рисунке 2.8. Структурные карты Джексона Техника структурных карт Джексона основана на методе структурного программирования Джексона, который выявляет соответствие между структурой потоков данных и структурой программы. Основное внимание в методе сконцентрировано на соответствии входных и выходных потоков данных. Структуры на диаграммах Джексона строятся из четырех основных компонентов, представленных на рис. 2.9: операция — блок кодов, имеющий один вход и один выход (рисунок 2.9, а); следование — последовательное выполнение операций слева направо (рисунок 2.9, б); выбор — выполнение одной из операций в зависимости от выполнения условия (рисунок 2.9, в); 25 итерация — многократное выполнение блока (рисунок 2.9, г). Рисунок 2.9 – Элементы структурных диаграмм Джексона Пример. У менеджера торговой фирмы имеется файл, содержащий записи о принтерах со следующими полями: фирма-производитель, марка, скорость печати, стоимость, количество единиц на складе. Эти поля образуют структуру входных данных. По запросу менеджера программа выдает сведения о нужных покупателю принтерах в соответствии с критерием поиска. Критерием может быть: цена, скорость или фирма-производитель. Выходными данными является список, содержащий наименования выбранных принтеров. С точки зрения структурного программировании Джексона алгоритм программы будет следующим: Программа Цикл пока не конец файла Прочитать запись Сравнить заданные поля с критерием поиска Если совпали Сохранить в выходной список Конец-если Конец-цикл Вывод результирующего списка Конец-программа 26 Рисунок 2.10 – Структурная карта Джексона Полученная структурная карта Джексона приведена на рисунке 2.10. CASE-технологии CASE-технологии (Computer-Aided Software/System Engineering — разработка программного обеспечения/систем с использованием компьютерной поддержки) — это реализованные в виде программных продуктов технологические системы, ориентированные на создание сложных программных систем и поддержку их полною жизненною цикла или его основных этапов. В настоящее время CASE-технологии используются не только для производства ПП, но и как мощный инструмент решения исследовательских и проектных задач (структурный анализ предметной области, моделирование деловых предложений с целью решения задач оперативного и стратегического планирования и управления ресурсами). CASE-технологии начали развиваться в связи с развитием методологии структурного программирования. Их развитие стало возможным благодаря тому, что формализация в структурном программировании оказалась наиболее приемлемой для автоматизации. Таким образом, CASE-средства являются результатом эволюционного развития отрасли инструментальных (или технологических) средств. CASE-средства обладают следующими основными достоинствами: повышают качество создаваемого ПО с помощью средств автоматического контроля; ускоряют процесс проектирования и разработки; позволяют за короткое время создавать прототип будущей системы, что позволяет на ранних этапах оценить ожидаемый результат; освобождают разработчика от рутинной работы, частично генерируя коды программ; поддерживают технологии повторного использования компонентов ПО; поддерживают развитие и сопровождение разработки. При использовании CASE-технологий изменяются фазы жизненного цикла программного продукта, как показано в таблице 2.2. Таблица 2.2 – Сравнительная характеристика этапов жизненного цикла ПО 27 Наиболее просто автоматизируемыми оказались стадии «контроль проекта» и «кодогенерация», хотя все остальные этапы Жизненного цикла ПО также поддерживаются СASЕ-технологнями. Кроме изменения содержания фаз, существенно изменилось Распределение трудозатрат по фазам, как показано в таблице 2.3. Таблица 2.3. Распределение трудозатрат по фазам жизненного цикла ПО Таблица 2.4 содержит сравнительную характеристику целей и содержания этапов жизненного цикла ПО при традиционной разработке и с помощью CASE-средств. Таблица 2.4 – Цели и содержание этапов жизненного цикла ПО CASE-технология базируется на спиральной модели жизненного цикла ПО. На начальных этапах жизненною цикла (анализ требований, проектирование спецификаций, предварительное и детальное проектирование) проверяется и обосновывается реализуемость технических решений путем создания прототипов. Эта работа повторяется на каждом витке спирали, причем каждый следующий виток характеризуется более высокой степенью детализации создаваемого ПО. Окончанием витка является уточнение целей и характеристик проекта и планирование 28 работ следующего витка спирали. Тем самым реализуется нисходящий принцип проектирования. Чем же принципиально CASE -технология отличается от традиционной технологии разработки ПО? Девизом разработчиков CASE-технологий является фраза «одна картинка стоит тысячи слов». Поэтому при использовании CASE-средств функционирование объекта (разрабатываемого ПО) отражается в различных схемах, таблицах, диаграммах, картах и т. п. Большинство CASE-технологий основано на парадигме методология/метод/нотация/ средство. Методология па основе некоторого подхода определяет шаги работы, их последовательность, а также правила распределения и назначения методов. Метод определяет способ достижения той или иной цели. Нотацией называют систему обозначений, используемых для описания структуры системы, элементов данных, этапов обработки и других компонентов. Нотации могут быть графические (представление моделей в виде таблиц, графов, диаграмм, схем и т. п.) и текстовые (описания моделей на формальных и естественных языках). Средства — инструментарий для поддержки методов. Эти инструменты обеспечивают работу пользователей-разработчиков при создании и редактировании проекта в интерактивном режиме, выполняют проверки соответствия компонентов и кодируют на некотором языке программирования модули ПО. Наиболее часто и эффективно в методологии структурного анализа используются следующие средства: DFD (Data Flow Diagrams) — диаграммы потоков данных совместно со словарями данных и спецификациями про ERD (Entity-Relationship Diagrams) диаграммы «сущность—связь»; STD (State Transition Diagrams) — диаграммы переходов состояний. Современные структурные методологии анализа и проектирования классифицируются по следующим признакам: по типу целевых систем — для систем реального времени и для информационных систем; по отношению к школам — Software Engineering (SE) и Information Engineering (IE); по порядку построения моделей — процедурно-ориентированные, ориентированные на данные и информационно-ориентированные. В таблице 2.5 приведены отличия информационных систем от систем реального времени. Таблица 2.5 – Отличия информационных систем от систем реального времени 29 SE применяется при разработке как информационных систем, так и систем реального времени и реализует нисходящий подход к проектированию ПО. Эта дисциплина более апробирована, так как появилась раньше IE. IE используется для проектирования информационных систем. Она новее, чем SE, и имеет более широкую область применения, поскольку является дисциплиной построения систем вообще, а не только систем ПО. Различие в порядке построения моделей трактуется следующим образом. Традиционный процедурно-ориентированный подход регламентирует первичность проектирования функциональных компонентов по отношению к проектированию структур данных. При подходе, ориентированном на данные, вход и выход являются наиболее важными — структуры данных определяются первыми, а процедурные компоненты являются производными от данных. Информационно-ориентированный подход позволяет работать с неиерархическими структурами данных. Ускорение разработки программного обеспечения. Методология RAD В связи с развитием CASЕ-технологий в рамках спиральной модели жизненного цикла ПО в последнее время широкое расраспространение получила методология быстрой разработки приложений RAD (Rapid Application Development). Процесс разработки при этом содержит три элемента: небольшую команду программистов (от 2 до 10 человек), что облегчает управление проектом; короткий, но тщательно проработанный производственный график (от 2 до 6 мес.), повышает эффективность работы; итерационный подход, при котором разработчики, по мере того как приложение начинает обретать форму, запрашивают и реализуют в продукте требования, полученные через взаимодействие с заказчиком. Команда разработчиков представляет собой группу профессионалов, имеющих опыт в анализе, проектировании, генерации кода и тестировании ПО с использованием CASE-средств. Кроме того, разработчики должны уметь, преобразовывать в рабочие прототипы предложения конечных пользователей. Жизненный цикл ПО методологии RAD состоит из четырех фаз: анализа и планирования требований; проектирования; реализации; внедрения. На фазе анализа и планирования происходит определение требований к разрабатываемому ПО силами пользователей под руководством специалистов-разработчиков. Пользователи системы определяют функции, которые она должна выполнять, выделяют те, которые требуют проработки в первую очередь, описывают информационные потребности. Определяется возможность реализации данного проекта в установленных рамках финансирования, на данных аппаратах средствах и т.п. Затем определяются временные рамки самого проекта в каждой из последующих фаз. Результатом данной фазы должны быть состав и приоритеты функций будущем ИС, предварительные функциональные и информационные модели ИС. На фазе проектирования часть пользователей под руководством специалистов-разработчиков принимает участие в техническом проектировании системы. Пользователи, непосредственно 30 взаимодействуя с разработчиками, уточняют и дополняют требования к системе, которые не были выявлены на фазе анализа и планирования требований. Для быстрого получения работающих прототипов приложений используются CASE-средства. Анализируется и при необходимости корректируется функциональная модель. Определяются требования разграничения доступа к данным. Каждый процесс рассматривается детально, и при необходимости для каждого элементарного процесса создается частичный прототип: экран, диалог, отчет, устраняющий неясности или неоднозначности. Здесь же выясняется, какой набор документации необходим для эксплуатации будущей системы. По результатам анализа процессов принимается решение о количестве, составляющих ИС подсистем, поддающихся разработке одной командой разработчиков за приемлемое для RADпроектов время — порядка 2—3 мес. Результатом данной фазы должны быть: общая информационная модель системы; функциональные модели системы в целом и подсистем, реализуемых отдельными командами разработчиков; точно определенные с помощью CASE-средства интерфейсы между автономно разрабатываемыми подсистемами; построенные прототипы экранов, отчетов, диалогов. Использование CASE-средств позволяет избежать искажения данных при передаче информации с фазы на фазу. Кроме того, в подходе RAD каждый прототип не выбрасывается после выполнения своей задачи, а развивается в часть будущей системы. Поэтому на следующую фазу передается уже более полная и полезная информация. На фазе реализации выполняется непосредственно сама быстрая разработка приложения. Программный код частично формируется с помощью автоматических генераторов CASEсредств. Для контроля за выполнением требований к ПО привлекаются конечные пользователи. Во время разработки осуществляется тестирование каждой полсистемы, что уменьшает стоимость исправления ошибок в коде программ по сравнению с тестированием уже готовой программной системы. Автономно разрабатываемые подсистемы постепенно внедряются в общую систему. При подключении очередной части производится тестирование. Затем осуществляется тестирование всей системы в целом. Завершается физическое проектирование системы. При этом производится анализ использования данных, если необходимо, создаются базы данных и подключаются к системе, определяются требования к аппаратным ресурсам, завершается разработка документации ПО и определяются способы увеличения производительности. Результатом фазы является готовая система, удовлетворяющая всем согласованным требованиям. На этапе внедрения проводят обучение пользователей, организационные изменения и постепенный переход на новую систему. При этом параллельно с новой системой продолжается эксплуатация старой системы до полного внедрения новой. Методология RAD не претендует на универсальность. Она хороша в первую очередь для относительно небольших проектов, разрабатываемых для конкретного заказчика, и неприменима для построения сложных расчетных программ, операционных систем или систем управления космическими кораблями, т.е. программ, требующих написания большого объема (сотни тысяч строк) уникального кода. Основные принципы методологии RAD: итерационная разработка приложений; 31 необязательность полного завершении работ на каждом из этапов жизненного цикла; применение CASE-средств, обеспечивающих целостность данных; участие конечных пользователей в процессе разработки ИС; разработка прототипов, позволяющая полнее потребности конечного пользователя; выяснить и удовлетворить тестирование, производимое параллельно с разработкой; разработка подсистем несколькими немногочисленными хорошо управляемыми командами профессионалов; четкое планирование и контроль выполнения работ. 2.2 Основные подходы к интегрированию программных модулей Модульное проектирование является одним из первых подходов к разработке структуры ПС и уже несколько десятилетий сохраняет свои позиции как в качестве классического подхода, так и в качестве основы для современных технологий разработки ПС. При разработке модульных ПС могут использоваться методы структурного проектирования или методы объектно-ориентированного проектирования. Их целью является формирование структуры создаваемой программы – ее разделение по некоторым установленным правилам на структурные компоненты (модуляризация) с последующей иерархической организацией данных компонентов. Для различных языков программирования такими компонентами могут быть подпрограммы, внешние модули, объекты и т.п. Обзор методов объектно-ориентированного анализа и проектирования приведен в разд. 6. В данном разделе рассмотрены методы структурного проектирования. Такие методы ориентированы на формирование структуры программного средства по функциональному признаку. Классическое определение идеальной модульной программы формулируется следующим образом. Модульная программа – это программа, в которой любую часть логической структуры можно изменить, не вызывая изменений в ее других частях. Признаки модульности программ: 1. программа состоит из модулей. Данный признак для модульной программы является очевидным; 2. модули являются независимыми. Это значит, что модуль можно изменять или модифицировать без последствий в других модулях; 3. условие «один вход – один выход». Модульная программа состоит из модулей, имеющих одну точку входа и одну точку выхода. В общем случае может быть более одного входа, но важно, чтобы точки входов были определены и другие модули не могли входить в данный модуль в произвольной точке. Достоинства модульного проектирования: 32 1. упрощение разработки ПС; 2. исключение чрезмерной детализации обработки данных; 3. упрощение сопровождения ПС; 4. облегчение чтения и понимания программ; 5. облегчение работы с данными, имеющими сложную структуру. Недостатки модульности: 1. модульный подход требует большего времени работы центрального процессора (в среднем на 5 – 10 %) за счет времени обращения к модулям; 2. модульность программы приводит к увеличению ее объема (в среднем на 5 – 10 %); 3. модульность требует дополнительной определенных навыков проектирования ПС. работы программиста и Классические методы структурного проектирования модульных ПС делятся на три основные группы: 1. методы нисходящего проектирования; 2. методы расширения ядра; 3. методы восходящего проектирования. На практике обычно применяются различные сочетания этих методов. В идеальной модульной программе любую часть логической структуры можно изменить, не вызывая изменений в ее других частях. Идеальная модульная программа состоит из независимых модулей, имеющих один вход и один выход. Модульные программы имеют достоинства и недостатки. Существует три группы классических методов проектирования модульных ПС. Для оценки корректности и эффективности структурного разбиения программы на модули необходимо оценить характеристики получившихся модулей. Существуют различные меры оценки характеристик модулей. Ниже рассматриваются две из них – связность и сцепление. Связность модуля Связность модуля определяется как мера независимости его частей. Чем выше связность модуля, тем больше отдельные части модуля зависят друг от друга и тем лучше результат проектирования. Для количественной оценки связности используется понятие силы связности модуля. Типы связности модулей и соответствующие им силы связности представлены в таблице 2.6. Модуль с функциональной связностью выполняет единственную функцию и реализуется обычно последовательностью операций в виде единого цикла. Если модуль спроектирован так, чтобы изолировать некоторый алгоритм, он имеет функциональную связность. Он не может быть разбит на два других модуля, имеющих связность того же типа. Примером модуля с функциональной связностью является, например, модуль сортировки дат. 33 Таблица 2.6 – Типы и силы связности модулей Связность Функциональная Последовательная Коммуникативная Процедурная Временная Логическая Связность по совпадению Сила связности 10 (сильная связность) 9 7 5 3 1 0 (слабая связность) Модуль, имеющий последовательную связность, может быть разбит на последовательные части, выполняющие независимые функции, совместно реализующие единую функцию. Модуль с последовательной связностью реализуется обычно как последовательность циклов или операций. Модуль, имеющий коммуникативную связность, может быть разбит на несколько функционально независимых модулей, использующих общую структуру данных. Общая структура данных является основой его организации как единого модуля. Если модуль спроектирован так, чтобы упростить работу со сложной структурой данных, изолировать эту структуру, он имеет коммуникативную связность. Такой модуль предназначен для выполнения нескольких различных и независимо используемых функций над структурой данных (например, запоминание некоторых данных, их поиск и редактирование). Процедурная связность характерна для модуля, управляющие конструкции которого организованы в соответствии со схемой алгоритма, но без выделения его функциональных частей. Такая структура модуля возникает, например, при расчленении длинной программы на части в соответствии с передачами управления, но без определения каких-либо функций при выборе разделительных точек; при группировании альтернативных частей программы; если для уменьшения размеров модуль с функциональной связностью делится на два модуля (например, исходный модуль содержит объявления, подпрограммы и раздел операторов для выполнения единой функции; после его разделения один модуль содержит объявления и подпрограммы, а другой – раздел операторов). Модуль, содержащий функционально не связанные части, необходимые в один и то же момент обработки, имеет временную связность (связность по классу). Данный тип связности имеет, например, модуль инициализации, реализующий все требуемые в начале выполнения программы функции и начальные установки. Для увеличения силы связности модуля функции инициализации целесообразно разделить между другими модулями, выполняющими обработку соответствующих переменных или файлов или включить их выполнение в управляющий модуль, но не выделять в отдельный модуль. Если в модуле объединены операторы только по принципу их функционального подобия (например, все они предназначены для проверки правильности данных), а для настройки модуля применяется алгоритм переключения, то модуль имеет логическую связность. Его части ничем не связаны, а лишь похожи. Например, модуль, состоящий из разнообразных подпрограмм обработки ошибок, имеет логическую связность. Однако если с помощью этого модуля может быть получена вся выходная информация об ошибках, то он имеет коммуникативную связность, поскольку изолирует данные об ошибках. Модуль имеет связность по совпадению, если его операторы объединяются произвольным образом. Модули верхних уровней иерархической структуры программы должны иметь функциональную или последовательную связность. Для модулей обслуживания предпочтительнее коммуникативная связность. Если модули имеют процедурную, временную, логическую связность или связность по совпадению, это свидетельствует о недостаточно 34 продуманном их проектировании. Необходимо добиваться функциональной связности проектируемых модулей. Сцепление модулей Сцепление модулей – это мера относительной независимости модулей. Сцепление влияет на сохранность модулей при модификациях и на понятность их исходных текстов. Слабое сцепление определяет высокий уровень независимости модулей. Независимые модули могут быть модифицированы без переделки других модулей. Два модуля являются полностью независимыми, если в каждом из них не используется никакая информация о другом модуле. Чем больше информации о другом модуле в них используется, тем менее они независимы и тем более сцеплены. Чем очевиднее взаимодействие двух связных друг с другом модулей, тем проще определить необходимую корректировку одного модуля, зависящую от изменений, производимых в другом. В таблице 2.7 содержатся типы сцепления модулей и соответствующие им степени сцепления. Таблица 2.7 - Типы и степени сцепления модулей Сцепление Независимое По данным По образцу По общей области По управлению По внешним ссылкам По кодам Степень сцепления 0 1 (слабое сцепление) 3 4 5 7 9 (сильное сцепление) Независимое сцепление возможно только в том случае, если модули не вызывают друг друга и не обрабатывают одну и ту же информацию. Модули сцеплены по данным, если они имеют общие простые элементы данных, передаваемые от одного модуля к другому как параметры. В вызывающем модуле определены только имя вызываемого модуля, типы и значения переменных, передаваемых как параметры. Вызываемый модуль может не содержать никакой информации о вызывающем. В этом случае изменения в структуре данных в одном из модулей не влияют на другой модуль. Например, в вызывающем модуле определена такая структура данных, как массив. В вызываемый модуль передается в качестве параметра элемент массива. При этом изменения в структуре данных вызывающего модуля не повлияют на вызываемый модуль. Модули со сцеплением по данным не имеют общей области данных (общих глобальных переменных). Если модули сцеплены по данным, то по изменениям, производимым в объявленных параметрах, легко можно определить модули, на которые эти изменения повлияют. Модули сцеплены по образцу, если в качестве параметров используются структуры данных (например, в качестве параметра передается массив). Недостаток такого сцепления заключается в том, что в обоих модулях должна содержаться информация о внутренней структуре данных. Если модифицируется структура данных в одном из модулей, то необходимо корректировать и другой модуль. Следовательно, увеличивается вероятность появления ошибок при разработке и сопровождении ПС. Модули сцеплены по общей области, если они имеют доступ к общей области памяти (например используют общие глобальные данные). В этом случае возможностей для появления ошибок при модификации структуры данных или одного из модулей намного больше, поскольку труднее определить модули, нуждающиеся в корректировке. Модули сцеплены по управлению, если какой-либо из них управляет решениями внутри другого с помощью передачи флагов, переключателей или кодов, предназначенных для выполнения функций управления. Таким образом, в одном из модулей содержится информация 35 о внутренних функциях другого. Например, если модуль имеет логическую связность и при его вызове используется переключатель требующейся функции, то вызываемый и вызывающий модули сцеплены по управлению. Модули сцеплены по внешним ссылкам, если у одного из них есть доступ к данным другого модуля через внешнюю точку входа. Таким путем осуществляется неявное влияние на функционирование другого модуля. Сцепление этого типа возникает, например, тогда, когда внутренние процедуры одного модуля оперируют с глобальными переменными другого модуля. Модули сцеплены по кодам, если коды их команд объединены друг с другом. Например, для одного из модулей доступны внутренние области другого модуля без обращения к его точкам входа, то есть модули используют общий участок памяти с командами. Это сцепление возникает, когда модули проектируются как отдельные подпрограммы, путь через которые начинается в различных точках входа, но приводит к общему сегменту кодов. Например, некоторый модуль реализует функции синуса и косинуса c учетом того, что Cos(x) = Sin(π/2 – x). Путь через точки входа Sin и Cos ведет к общему участку команд модуля. Следует иметь в виду, что если модули косвенно обращаются друг к другу (например, связь между ними осуществляется через промежуточные модули), то между ними также существует сцепление. Резюме Различают независимое сцепление модулей, сцепление по данным, по образцу, по общей области, по управлению, по внешним ссылкам, по кодам. Сцепление модулей зависит от спроектированной структуры данных и способов взаимодействия между модулями. Необходимо использовать простые параметры и не применять общих областей памяти. 2.3 Модульная структура программных продуктов Модульная структура программы представляет собой древо видную структуру, в узлах которой размещаются программные модули, а направленные дуги показывают статическую подчиненность модулей. Если в тексте модуля имеется ссылка на другой модуль, то их на структурной схеме соединяет дуга, которая исходит из первого и входит во второй модуль. Другими слова ми, каждый модуль может обращаться к подчиненным ему модулям. При этом модульная структура программной системы, кроме структурной схемы, должна включать в себя еще и совокупность спецификации модулей, образующих эту систему. Функция верхнего уровня обеспечивается главным модулем; он управляет выполнением нижестоящих функций, которым соответствуют подчиненные модули. При определении набора модулей, реализующих функции конкретного алгоритма, необходимо учитывать следующее: 1. модуль вызывается на выполнение вышестоящим по иерархии модулем и, закончив работу, возвращает ему управление; 2. принятие основных решений в алгоритме выносится на максимально высокий по иерархии уровень; 3. если в разных местах алгоритма используется одна и та же функция, то она оформляется в отдельный модуль, который будет вызываться по мере необходимости. Состав, назначение и характер использования программных модулей в значительной степени определяются инструментальными средствами. Например, при разработке СУБД используются следующие программные модули: 1. экранные формы ввода и/или редактирования информации базы данных; 36 2. отчеты; 3. макросы; 4. стандартные средства для обработки информации; 5. меню для выбора функции обработки и др. Методы разработки при модульном программировании Спецификация программного модуля состоит из функциональной спецификации модуля, описывающей семантику функций, выполняемых этим модулем по каждому из его входов, и синтаксической спецификации его входов, позволяющей по строить на используемом языке программирования синтаксически правильное обращение к нему. Функциональная спецификация модуля определяется теми же принципами, что и функциональная спецификация программной системы. Существуют разные методы разработки модульной структуры программы, в зависимости от которых определяется порядок программирования и отладки модулей, указанных в этой структуре. Обычно а литературе обсуждаются два метода: метод восходящей разработки и метод нисходящей разработки. Метод восходящей разработки Сначала строится древовидная модульная структура программы. Затем поочередно проектируются и разрабатываются модули программы, начиная с модулей самого нижнего уровня, затем предыдущего уровни и т. д. То есть модули реализуются в таком порядке, чтобы для каждого программируемого модуля были уже запрограммированы все модули, к которым он может обращаться. После того как все модули программы запрограммированы, производится их поочередное тестирование и отладка в таком же что каждый модуль при программировании выражается через уже запрограммированные непосредственно подчиненные моду ли, а при тестировании использует уже отлаженные модули. Недостатки метода восходящей разработки заключаются в следующем: на нижних уровнях модульной структуры спецификации могут быть еще определены не полностью, что может привести к полной переработке этих модулей после уточнения спецификаций на верхнем уровне; для восходящего тестирования всех модулей кроме головного, который является модулем самого верхнего уровня, приходится создавать вызывающие программы, что приводит к созданию большого количества отладочного материала, но не гарантирует, что результаты тестирования верны; головной модуль проектируется и реализуется в последнюю очередь, что не дает продемонстрировать его заказчику для уточнения спецификаций. Метод нисходящей разработки Как и в предыдущем метоле, сначала строится модульная структура программы в виде дерева. Затем проектируются и реализуются модули программы, начиная с модуля самого верх него уровня — головного, далее разрабатываются модули уровнем ниже и т. д. При этом переход к программированию какого-либо модуля осуществляется только в том случае, если уже запрограммирован модуль, который к нему обращается. Затем производится их поочередное тестирование и отладка в таком же нисходящем порядке. При таком порядке разработки про граммы вся необходимая глобальная информация формируется своевременно, т. с. 37 ликвидируется весьма неприятный источник просчетов при программировании модулей. Существенно облегчается и тестирование модулей, производимое при нисходящем тестировании программы. Первым тестируется головной модуль программы, который представляет всю тестируемую программу, при этом все модули, к которым может обращаться головной, заменяются их имитаторами (так называемыми «заглушками» )- Каждый имитатор модуля является простым программным фрагментом, реализующим сам факт обращения к данному модулю с необходимой для правильной работы программы обработкой значений его входных параметров и с выдачей, если это необходимо, подходящего результата. Далее производится тестирование следующих по уровню модулей. Для этого имитатор выбранного для тестирования модуля заменяется самим модулем, и добавляются имитаторы модулей, к которым может обращаться тестируемый модуль. При таком подходе каждый модуль будет тестироваться в«естественных» состояниях ин формационной среды, возникающих к моменту обращения к этому модулю при выполнении тестируемой программы. Таким образом, большой объем «отладочного» программирования за меняется программированием достаточно простых имитаторов используемых в программе модулей. Недостатком нисходящего подхода к программированию является необходимость абстрагироваться от реальных возможностей выбранного языка программирования и придумывать абстрактные операции, которые позже будут реализованы с помощью модулей. Однако способность к таким абстракциям является необходимым условием разработки больших программных средств. Рассмотренные выше методы (нисходящей и восходящей разработок), являющиеся классическими, требуют, чтобы мо дульная древовидная структура была готова до начала программирования модулей. Как правило, точно и содержательно разработать структуру программы до начала программирования не возможно. При конструктивном и архитектурном подходах к разработке модульная структур формируется в процессе реализации модулей. Конструктивный подход Конструктивный подход к разработке программы представляет собой модификацию нисходящей разработки, при которой модульная древовидная структура программы формируется в процессе программирования модуля. Сначала программируется головной модуль, исходя из спецификации программы в целом (спецификация программы является одновременно спецификацией головного модуля). В процессе программирования головного модуля в случае, если эта программа достаточно большая, выделяются подзадачи (некоторые функции) и для них создаются спецификации реализующих эти подзадачи фрагментов про граммы. В дальнейшем каждый из этих фрагментов будет представлен поддеревом модулей (спецификация выделенной функции является одновременно спецификацией головного модуля этого поддерева). Таким образом, на первом шаге разработки программы (при программировании ее головного модуля) формируется верхняя часть дерева, например, как на рисунке 2.11. 38 Рисунок 2.12 – Первый шаг формирования модульной структуры программы По тому же принципу производится программирование следующих по уровню специфицированных, но еще не запрограммированных модулей в соответствии со сформированным деревом. Рисунок 2.12 – Второй шаг формировании модульной структуры программы при конструктивном подходе В результате к дереву добавляются очередные уровни, как показано на рис. 2.12. 39 Архитектурный подход Архитектурный подход к разработке программы представляет собой модификацию восходящей разработки, при которой мо дульная структура программы формируется в процессе программирования модуля. Целью разработки в данном методе является повышение уровня языка программирования, а не разработка конкретной программы. Это означает, что для заданной предметной области выделяются типичные функции, специфицируются, а затем и программируются отдельные программные моду ли, выполняющие эти функции. Сначала в виде модулей реализуются более простые функции, а затем создаются модули, использующие уже имеющиеся функции, и т. д. Это позволяет существенно сократить трудозатраты на разработку конкретной программы путем подключения к ней уже имеющихся и проверенных на практике модульных структур нижнего уровня, что также позволяет бороться с дублированием в программировании. В связи с этим программные модули, создаваемые в рамках архитектурного подхода, обычно параметризуются для того, чтобы облегчить их применение настройкой параметров. Нисходящая реализация В классическом методе нисходящей разработки сначала асе модули разрабатываемой программы программируются, а затем тестируются в нисходящем порядке. При этом тестирование и отладка модулей могут привести к изменению спецификации подчиненных модулей и даже к изменению самой модульной структуры программы. В результате может оказаться, что часть модулей вообще не нужна в данной структуре, а часть модулей придется переписывать. Более рациональна каждый запрограммированный модуль тестировать сразу же до перехода к программированию другого модуля. Такой метод в литературе получил название метода нисходящей реализации. Целенаправленная конструктивная реализация В зависимости от того, в какой последовательности в процессе разработки программы обходятся узлы дерева, существуют разновидности описанных выше методов. Например, метод целенаправленной конструктивной реализации, при котором в рамках конструктивного подхода реализуются сначала модули, необходимые для самого простого рабочего варианта программы, остальные модули заменяются их имитаторами. Затем к имеющемуся варианту добавляются другие модули, обеспечивающие работу программы для других наборов данных, и так далее до полной реализации программы. Достоинством этого метода является то, что уже на достаточно ранней стадии создается работающий вариант разрабатываемой программы. Психологически это играет роль допинга, резко повышающего эффективность разработчика. Подводя итог сказанному, на рис. 2.13 представлена общая схема классификации рассмотренных методов разработки структуры программы. 40 Рисунок 2.13 - Классификация методов разработки структуры программ Контрольные вопросы 1. Приведите пример структурной схемы ПО. 2. Опишите основные элементы функциональных схем ПО. 41 3. Как составляются структурные схемы Константайна? 4. Как составляются структурные карты Джексона? 5. Что такое CASE-технологии? 6. Что такое RAD-технологии? 7. Что такое связность модуля? 8. Назовите и охарактеризуйте типы и силы связности модулей. 9. Что такое сцепление модулей? 10. модулей. Назовите и охарактеризуйте типы и степени сцепления 42 3 Методологии моделирования предметной области 3.1 Основные принципы разработки надежного программного обеспечения Прежде всего необходимо сказать, что в данной работе подразумевается под термином «надежное программное обеспечение». Надежное ПО – это программное обеспечение, способное с высокой вероятностью выполнять свою целевую функцию в заданных условиях. Под условиями понимаются программно-аппаратное окружение ПО, заданное время работы, различные ограничения и требования, накладываемые на работу ПО. Надежное программное обеспечение должно обладать свойствами: безотказности, работоспособности, устойчивости к ошибкам. Если к надежному программному обеспечению предъявляется еще одно требование – безопасная работа, под которым понимается невозможность ПО быть причиной или участвовать в причинении человеку физического вреда, то такое программное обеспечение будем называть «безопасным» или «критическим», а программно-аппаратные системы, в которых оно работает – «критическими системами». Рекомендации стандартов DO178B/DO178С непосредственно относятся к этому программному обеспечению. Для критического программного обеспечения также задаются определенные значения вероятности возникновения отказов, которые оно обязано соблюдать. Любое другое программное обеспечение, для которого требование безопасности не выдвигается, будем назвать «обычным ПО» или «некритическим ПО». Далее будет часто использоваться термин "жизненный цикл разработки программного обеспечения". Под ним подразумевается часть жизненного цикла программного обеспечения, которая не включает в себя этапы поддержки и обслуживания. Набор приведенных ниже принципов описывает черты процесса создания ПО, без которых, по мнению автора, нельзя обойтись при разработке надежного ПО. Все они построены на базе рекомендаций, приведенных в авиационных стандартах DO178B/DO178С, и опыта автора по сертификации ПО, согласно этим стандартам. В отличие от принципов разработки критического ПО, приведенные ниже принципы, как правило, гораздо менее жесткие, чем те, что устанавливают авиационные стандарты, поскольку речь идет о надежном ПО, а не о том, которое может причинить вред здоровью человека. Для каждого принципа дается пояснение что под ним подразумевается и то как его можно применить для разработки надежного программного обеспечения. Определение процесса разработки ПО Невозможно разработать качественный программный продукт, если процесс его создания является неупорядоченным и бессистемным. Только в результате строго регламентированного процесса можно создать что-то по-настоящему стоящее – утверждают авиационные стандарты. Создание такого процесса является первым шагом в сторону качественного программного обеспечения. Любая разработка ПО должна начинаться с определения того, что из себя будет представлять весь процесс разработки, какой модели жизненного цикла он будет придерживаться, какие основные процессы должны в него входить. Выбранная модель жизненного цикла позволит упорядочить разработку путем установки всех его основных этапов. Для каждого этапа разработки необходимо наметить цели, а также установить способы их достижения. Выбранную модель жизненного цикла нужно строго соблюдать, и она не может быть изменена в процессе разработки. Смена модели разработки отбрасывает проект к самому его началу. На сегодняшний день существует множество различных моделей жизненного цикла и, в принципе, почти все они подходят для разработки надежного и качественного ПО. Нельзя со строгой определенностью сказать, что в результате следования вот этой модели программный продукт получается более надежным, нежели в результате разработки согласно той. Для разработки надежного ПО главное – это выполнение установленных целей и задач по 43 обеспечению надежности и строгое соблюдение всех правил, диктуемых моделью. Поэтому нет особого смысла для получения более надежного ПО переходить на другую модель, если есть хороший опыт использования определенного типа модели. Авиационные стандарты не требуют использования какой-то определенной модели жизненного цикла разработки, но они устанавливают набор процессов, которые обязательно должны в него входить. Для каждого из этих процессов они определяют цели и задачи, которые должны быть выполнены, а также виды деятельности, которые должны быть осуществлены. Для разработки бортового программного обеспечения часто используют V-модель жизненного цикла, спиральную модель разработки или их гибридные варианты. Рассмотрение вопросов надежности на каждом из этапов разработки Ключевым отличием разработки критического программного обеспечения от разработки обычного (не связанного с безопасностью) является частичное смещение приоритетов. Для некритического программного обеспечения главными являются требования, установленные его заказчиком или требования, диктуемые его намеченной функцией. Для критического программного обеспечения его безопасная работа более важна, чем функциональность. Поэтому любые действия каждого из процессов, участвующих в работе программного обеспечения, должны быть оценены с точки зрения безопасности. Для надежного программного обеспечения требования надежности должны быть, по крайней мере, на одном уровне с требованиями к его функциональности. Если мы хотим, чтобы наше программное обеспечение было надежным, даже если мы не разрабатываем критическое ПО, то об этом поздно вспоминать в момент, когда уже начато тестирование. Каждый разработанный план, каждый вид деятельности любого из процессов, входящих в жизненный цикл разработки, каждое функциональное требование и тестовая функция, должны быть рассмотрены через призму надежности. Мы постоянно должны задаваться вопросами: наши действия повышают или понижают надежность ПО; если понижают, то как этого избежать, как сделать так, чтобы надежность не пострадала, что еще можно сделать для стабильной работы, достаточно ли мы приложили усилий, чтобы это правильно работало. Если во время процесса разработки надежного ПО возникла необходимость изменить или дополнить функциональные возможности программного обеспечения, то должна быть произведена оценка того, как эти изменения повлияет на надежность работы всего программного продукта. Если такое влияние обнаруживается, все действия по обеспечению надежности, в том числе планы, требования, тесты, должны быть пересмотрены, чтобы учесть это влияние. Было бы хорошей идеей во время процесса планирования описать, какие функциональные требования к программному обеспечению являются жестко фиксированными, так что при их смене процесс разработки должен будет начаться сначала, а какие могут быть изменены без рестарта этого процесса. Доказательство надежности Ничего не берется на веру – все нужно доказать. Этот принцип – один из основополагающих при разработке надежного и безопасного программного обеспечения. Стандарты DO178B/DO178С однозначно говорят, что если мы не можем доказать, что наше программное обеспечение безопасно – значит оно не является таковым, и его нельзя использовать в критических системах. То же в полной мере относится и к надежному программному обеспечению – без доказательств надежности ПО к нему не должно быть доверия. Авиационные стандарты требуют, чтобы для доказательства правильности любых действий были представлены артефакты, которые создаются в процессе осуществления этих действий. К артефактам относятся различные документы, данные, результаты тестирования, исходный код и другое – все, что производят процессы, входящие в жизненный цикл разработки. По ним судят о том, насколько успешно проходит или проходил тот или иной процесс, какие возникли проблемы, какие действия были предприняты по их устранению, как в результате эти проблемы были разрешены. 44 Стандарты DO178B/DO178С устанавливают определенные требования к артефактам жизненного цикла. Каждый артефакт должен принадлежать к одной из двух категорий в зависимости от их важности. Артефакты, принадлежащие к первой категории, должны иметь конфигурационную идентификацию, должно быть понятно, кто их создал и с каким другими артефактами они связаны, они должны быть закрыты от несанкционированного доступа и должна быть возможность их восстановления. К артефактам, принадлежащим ко второй категории, предъявляются более жесткие требования. Эти требования включают все требования первой категории, плюс дополнительные действия по мониторингу и ревизии их изменений, а также устанавливаются определенные требования к физическому носителю информации, на котором они располагаются. Требования к артефактам, создаваемым в процессе разработки надежного ПО, и требования к операциям с ними должны быть определены в самом начале разработки. Сами разработчики должны решить, что необходимо включить в список этих требований. Базовыми требованиями для артефактов надежного ПО должно быть соответствие определенному стандарту и нахождение их под конфигурационным контролем. Планирование Говоря о планировании, вспоминаются достаточно верные слова персонажа Хита Леджера из кинофильма Кристофера Нолана “Темный рыцарь”: “Никто не паникует, если все идет согласно плану, если даже план чудовищен”. Опыт разработки критического программного обеспечения утверждает, что невозможно создать надежного ПО, если нет детального плана действий. Планирование – это ключевой этап жизненного цикла разработки безопасного и надежно ПО. Суть процесса разработки безопасного программного обеспечения можно выразить одной фразой: сначала мы создаем план, затем мы действуем в соответствии с этим планом, постоянно проверяя, что мы делаем именно то, что запланировали. Шаг в сторону – и мы теряем безопасность. Планы могут быть скорректированы, но и процедура изменения также должна проводиться по определенному плану. Процесс планирования также является критически важным этапом разработки надежного программного обеспечения, и он должен быть обязательно включен в жизненный цикл разработки. Целями процесса планирования являются: определение всех составляющих жизненного цикла разработки ПО, выбор программного и аппаратного окружения, включая инструменты разработки, описание всех видов деятельности и создание планов для каждого из процесса, входящего в жизненный цикл, определение используемых стандартов, а также решение вопросов о том, как будут проходить ревизии и обновления всех созданных документов. Важное место в процессе планирования надежного ПО должно быть уделено анализу возможного возникновения ошибок и нештатных ситуаций, которые могут привести к аварийной ситуации, и должны быть предложены пути их устранения. Стандарты DO178B/DO178С требуют, чтобы перед началом разработки были созданы следующие планы: План разработки. План верификации. План обеспечения качества. План управления конфигурации. План разработки содержит: описание всего жизненного цикла разработки ПО, ссылки на все используемые стандарты, 45 полное описание производственного окружения, такого как аппаратное обеспечение, компилятор, компоновщик, инструменты разработки и дизайна. План верификации содержит в себе все, что касается процедур верификации: какие методы верификации должны быть произведены, как и когда они должны проходить, кто в них должен принимать участие. Главным вопрос, на который отвечает план обеспечения качества – это то, какие действия будут проводиться для обеспечения качества. К этим действиям относятся различные аудиты, инспекции и мониторинги качества. План управления конфигурации говорит о том, как будут идентифицироваться, храниться и контролироваться все данные, создаваемые за время жизненного цикла разработки ПО, какие инструменты будут для этого использоваться. Для сертификации ПО согласно DO178B/DO178С, кроме перечисленных выше планов, сертификационному органу нужно еще представить План Программных Аспектов Сертификации (Plan for Software Aspects of Certification). Этот план, по сути, является контрактом между заявителем и сертификационным органом, и он должен быть согласован перед началом всего процесса. План содержит информацию о том, как будет проходить весь процесс разработки и взаимодействия с сертификационной властью. План также включает в себя обзор системы, где будет использоваться ПО, обзор самого разрабатываемого ПО, информацию о том, какие действия для безопасной работы ПО будут предприняты, описание жизненного цикла разработки, список создаваемых артефактов, производственный график и другое. Из требований авиационных стандартов можно заключить, что если вы используете методологии разработки, не включающие процесса планирования, например, Гибкие Методологии Разработки, такие как Экстремальное Программирование, DSDM и другие, вы не можете создать ПО, которое годится для использования в критических системах. На данный момент существует множество различных предложений о том, как адаптировать Гибкие Методологии Разработки так, чтобы они удовлетворяли требованиям безопасного программного обеспечения. Но какие-либо реальные воплощения этих идей на практике для разработки и сертификации авиационного программного обеспечения автору этой статьи неизвестны. Процесс сертификации ПО в авиации требует больших затрат, и кажется маловероятным, что какая-нибудь компания рискнет своими ресурсами, отойдя от принятой практики разработки ПО, чтобы проверить, работают ли Гибкие Методологии Разработки в ее индустрии. Вопрос о том можно ли создать надежное ПО, используя Гибкие Методологии Разработки, для систем, не связанных с безопасностью, также требует дополнительного исследования. Использование стандартов Чем большее число стандартов используется в процессе разработки программного обеспечения, тем лучше. Стандарты концентрируют в себе лучший практический опыт. Стандартизация документов может сделать эти документы более понятными и лучше воспринимаемыми другими людьми, а также позволяет избежать некоторых типов ошибок. Согласно требованиям авиационной сертификации, в процессе разработки ПО должны быть использованы как минимум три стандарта: Стандарт требований. Стандарт дизайна. Стандарт кодирования. Стандарт требований должен описывать методы, правила и инструменты, применяемые для разработки требований, их формат и нотацию. 46 В стандарте дизайна содержатся правила, регламентирующие архитектуру программного обеспечения, указываются приемлемые и неприемлемые методы дизайна, описываются принимаемые ограничения, например, запрет на использование рекурсии или максимальная вложенность вызовов и другое. Стандарт кода регламентирует все, что касается исходного кода: ссылки на описания используемого языка программирования и его синтаксиса, описание ограничений, накладываемых на этот язык, описание желательных и нежелательных конструкций языка, соглашение о наименовании переменных и функций, соглашение о том, как должен выглядеть код и любые другие правила, напрямую касающиеся написания кода. Какие стандарты использовать, определяется в процессе планирования. Могут применяться как самостоятельно разработанные, так и общеизвестные, широко используемые стандарты. Они задают правила, которые должны действовать на всем протяжении жизненного цикла. Например, если в стандарте кодирования написано, что нельзя вставлять комментарии в код, а все комментарии должны быть сконцентрированы в определенном документе, то, хотя это правило можно считать спорным, все комментарии из кода должны быть удалены. Несоответствие стандарту является серьезной ошибкой: либо оно должно быть устранено, либо необходимо поменять сам стандарт. Разработка надежного ПО также не может обойтись без использования стандартов кодирования, требований и дизайна. То, какие будут использованы стандарты, и что они в себя будут включать, должно быть решено в процессе планирования. Создание качественных требований Без требований к выполняемой функции нельзя создать ПО, неясные и размытые требования никогда не позволят создать качественное ПО. Требования – это фундамент разработки. От того, насколько хорошо они написаны, зависит то, насколько надежным будет программное обеспечение. Процесс непосредственной разработки ПО должен начинаться с процесса создания требований и вестись в соответствии с планом, определенным в процессе планирования. При разработке критического ПО требования принято разделять на два типа – высокоуровневые и низкоуровневые требования. Требования, относящиеся к первому типу, отвечают на вопрос "что мы собираемся делать", а требования ко второму типу отвечают на вопрос "как мы это будем делать". Высокоуровневые требования создаются непосредственно из системных требований и закладываемой функциональности ПО. На основании этих требованный строится дизайн и архитектура ПО. Уже на основе планируемого дизайна создаются низкоуровневые требования. Они адресуются непосредственно к коду. На основе низкоуровневых требований создается исходный код. Требования считаются качественными, если они конкретны и корректны, соответствуют функциональности ПО, если их можно верифицировать, если они уникальны, последовательны и непротиворечивы. Требования могут разбиваться на подуровни для удобства внесения в них изменений и трассировки. Для автоматизации и унификации процесса создания и отслеживания требований существует большое количество различных платных и бесплатных программ. Использование инструментов для работы с требованиями, как правило, положительно сказывается на качестве разрабатываемого ПО. Разделение процедуры проверки на два независимых процесса Для создания критического ПО проверка на правильность должна быть разделена на две независимые проверки – верификацию и валидацию. Несмотря на схожесть терминов, процесс верификации (verification) и процесс валидации (validation) имеют совсем разные смыслы. Верификация относятся к процессу контроля качества, она проверяет то, что мы разрабатываем ПО правильно, в соответствии с установленными планами и нормами. Валидация относится к процессу обеспечения качества, она проверяет, что разрабатываемое нами ПО выполняет свою 47 намеченную функцию. Другими словами, валидация задает вопрос: "Мы делаем правильную вещь?", а верификация: "Мы делаем ее правильно?". Во время верификации для нас неважно, какой программный продукт мы создаем, и какие функции он выполняет, важно, что мы делаем его правильно. А все, что относится к проверке функциональности ПО, ложится на валидацию. И валидация, и верификация необходимы при создании надежного ПО. Нарушение любого из этих принципов может привести к потере надежности. Они не должны проходить одновременно. Сначала необходимо убедиться, что мы делаем то, что нам нужно, а уже затем проверять, что процесс создания программного обеспечения идет в соответствии с намеченными планами и целями. Трассировка Ничего не создается само по себе: ни требование, ни код, ни тестовая процедура – это один из базовых принципов разработки надежного и безопасного кода, называемый трассировкой. Трассировка – это доказательство связи между элементами. Она показывает связь между различными процессами, между результатами и их порождающим процессом, между требованием и его реализацией, между рапортом об ошибке и самой ошибкой, и так далее. Трассировка позволяет понять, что из чего вышло и куда в результате пришло. Авиационные стандарты говорят: вы должны суметь проследить цепочку от результатов тестирования к самим тестам, от тестов к бинарному коду, от бинарного кода к исходному коду, от исходного кода к низкоуровневым требованиям, от низкоуровневых требований к дизайну и архитектуре, от дизайна и архитектуры к высокоуровневым требованиям, от высокоуровневых требований к системным требованиям и в обратную сторону. Трассировка должна быть двухсторонней. Стандарты не определяют метода показа трассировки, нужно только чтобы трассировка была продемонстрирована каким-либо образом. Например, с помощью различных ссылок одних документов на другие. Поэтому очень важно, чтобы все документы имели уникальную идентификацию, включающую, помимо прочего, и версию документа. Разработка надежного ПО также не может обойтись без трассировки. Определение критериев перехода между процессами Процессы, входящие в жизненный цикл разработки, могут использовать результаты работы одних процессов и передавать результаты своей работы другим процессам. Если не определить правила, когда каждый из процессов может считаться завершенным, и результаты его работы могут быть использованы другими процессами, то можно нарушить описанный выше принцип трассировки. Например, мы не можем перейти к процессу созданию низкоуровневых требований, если мы еще не создали соответствующие им высокоуровневые требования. Для того чтобы понять, когда следует завершать один процесс и переходить к другому, служат критерии перехода между процессами. Критерии перехода устанавливают, что должно быть сделано соответствующим процессом и какие минимально-достаточные условия должны быть выполнены, чтобы считать процесс завершенным, и чтобы можно было переходить к другому процессу. Например, если все изменения кода выполнены, то можно переходить к тестированию. Процесс обеспечения качества надежного ПО должен использовать эти критерии для оценки успешного завершения каждого из процессов, входящих в жизненный цикл разработки. Процесс верификации Наверно, есть разработчики, которые, создавая программное обеспечение, не допускают ни одной ошибки, и их программы работают правильно во всех возможных ситуациях. Если вы не относитесь к такому типу разработчиков, без процесса верификации вам не обойтись. Процесс верификации как раз и занимается выявлением и информированием об ошибках, которые могут появиться на всем протяжении жизненного цикла ПО. Для надежного ПО этот процесс должен проверять не только программный код, но и результаты работы других 48 процессов жизненного цикла, в том числе он должен отслеживать ошибки в требованиях, дизайне, тестирующих примерах, процедурах и результатах тестирования. При создании надежного программного обеспечения этот процесс, кроме тестирования, должен использовать такие методы верификации, как ревизия и анализ. Под ревизией понимается инспекция выходной информации исследуемого процесса в соответствии с контрольным перечнем, который должен быть составлен заранее. Анализ экзаменует функциональность, производительность, источники требований, полноту тестирования, безопасность компонента ПО, а также его взаимоотношения с другими компонентами ПО. Анализ может выявить противоречия и несоответствия в спецификации, стандартах, требованиях, дизайне и коде. Как проходит и какие цели выполняет процесс верификации, должно быть определено в соответствующем плане. Стандарты разработки критического ПО требуют, чтобы план верификации включал описания: Как происходит верификация. Кто персонально занимается верификацией. Какие методы должны быть использованы для ревизии, анализа и тестирования Какие процедуры будут задействованы для тестирования, какие тестовые данные будут созданы, и какие тестовые процедуры используются. Какое окружение используется для верификации: инструменты, аппаратная часть, процедуры и все что нужно для верификации. Критерии перехода: когда начинается процесс верификации; Как делается повторная верификация, что делать, если процесс уже завершен, и была найдена ошибка. Процесс управления конфигурацией Бесконтрольный доступ и изменение данных жизненного цикла ПО может привести к полной его остановке или потере всех созданных артефактов. Поэтому в любой жизненный цикл разработки надежного ПО обязательно должен входить процесс управления конфигурацией, контролирующий все то, что создается на всем протяжении жизненного цикла разработки ПО. Процесс управления конфигурации занимается идентификацией всех конфигурационных элементов, контролем их изменений и доступа, созданием базовых линий для отслеживания последующих модификаций; он осуществляет действия по оповещению, трассировке и коррекции проблем. Он также отвечает за архивацию и восстановление всех конфигурационных элементов, включая программное обеспечение. Процесс управления конфигурации начинается в тот момент, когда принято решение, что накопленные материалы, такие как чертежи, схемы, требования, любые другие документы, достаточны для начала процесса планирования. Этот процесс действует на всем протяжении жизненного цикла ПО в соответствии с разработанным планом. Стандарты DO178B/DO178С требуют, чтобы план управления конфигурации описывал: Какие инструменты используются для управления конфигурацией. Все типы контролируемых данных. Как данные будут храниться и выдаваться, например, выдача данных может осуществляться по интернету в зашифрованном виде. 49 Как хранится и контролируется код, в том числе описание того, на каких физических носителях он хранится, как осуществляются процедуры резервного копирования и восстановления кода. Процесс обеспечения качества При разработке программного обеспечения всегда есть вероятность, что что-то идет не так, что какой-то из процессов, входящих в жизненный цикл, работает неправильно, и что есть расхождения с установленным планом. Процесс обеспечения качества занимается выявлением таких проблем. Надежное программное обеспечение нельзя создать, если в жизненный цикл его разработки не включен этот процесс. Процесс обеспечения качества должен отслеживать, что все процессы идут в соответствии с намеченными планами, что они выполняют все установленные цели, что требования стандартов соблюдаются, переходы между процессами осуществляются в соответствии с установленными критериями, все артефакты соответствуют установленной спецификации. При возникновении проблем во время жизненного цикла разработки процесс обеспечения качества должен гарантировать, что они будут рассмотрены и по ним будут приняты соответствующие решения, и в конечном итоге они будут разрешены. Процесс верификации оценивает деятельность всех процессов, входящих в жизненный цикл разработки, с помощь различных аудитов и ревизий. Результатами работы процесса являются его записи. Они содержат информацию об проведенных аудитах, записи о санкционированных отклонениях и записи, подтверждающие проведение ревизий. Процесс верификации проводится в соответствии с разработанным планом, который для критического ПО должен включать следующие описания: Окружение обеспечения качества, а именно: инструменты, процедуры, стандарты, в чем заключается обеспечение качества, как организован процесс обеспечения качества, и кто за что в нем отвечает и перед кем. Действия по обеспечению качества: аудиты, рапорты, инспекции, мониторинг, контроль процессов жизненного цикла, отслеживание запросов на изменение и проблемных рапортов, и их мониторинг. Критерии перехода для процесса обеспечения качества, контрольные списки того, что должно быть проверено. Частота и последовательность действий процесса обеспечения качества. Список всех данных, создаваемых за время работы процесса, например протоколы митингов, записи проверок, записи установленных отклонений от процессов. Ведение истории разработки программного обеспечения Любые действия, проводимые на всем протяжении жизненного цикла разработки ПО, должны быть отражены в соответствующих документах. Необходимо также хранить информацию, кем они были совершены, и результаты этих действий. Все артефакты, произведенные за время ЖЦ разработки, составляют ее историю. История продукта должна показать, как поэтапно было создано программное обеспечение, что это за программное обеспечение, зачем оно нужно, какие системные и функциональные требования были в нее заложены, как осуществлялся процесс ее создания, контроля и проверки, почему данная система является надежной, как это было доказано. 50 Для критического программного обеспечения история создания ПО имеет очень важное значение, поскольку она может быть использована для расследования инцидентов, произошедших на системах, где это ПО было использовано. Может возникнуть ситуация, когда в суде нам придется рассказывать поэтапную работу над созданием нашего ПО и доказывать, что все что мы сделали, является правильным. Поэтому если задать вопрос авиационному сертифицирующему органу, какую информацию, какие данные и какие документы нужно хранить для сертификации программного обеспечения, они отвечают: все, что касается проекта и любых действий, проводимых в его рамках, включая даже и неформальную информацию, такую как мнения, обсуждения, записи переговоров и так далее. Для надежного ПО требование по хранению всей созданной за время разработки информации является чрезмерными. Но все, что непосредственно касается проекта, должно быть сохранено. Независимое проведение процедур проверки Для сертификации критического программного обеспечения стандарты DO178B/DO178С устанавливают 5 различных уровней безопасности ПО, от катастрофического, когда ошибочная работа программного обеспечения может привести к гибели людей, до уровня, когда ПО никак не может повлиять на безопасность полета. Сертификации ПО для разных уровней существенно отличается, и одним из основных отличий является то, как проходят процессы верификация и валидация. Чем выше уровень критичности ПО, тем выше требования к тому, чтобы процессы верификации и валидации на различных этапах разработки проводили люди, не имеющие прямого отношения к процессу разработки проверяемого ПО. Для сертификации на самые критические уровни безопасности требуется, чтобы всю верификацию и валидацию проводили только независимые от разработчика данного ПО люди. Для создания надежного программного обеспечения принцип независимости также имеет существенное значение. Необходимо, чтобы процедуру верификации и валидации результатов работы различных процессов (в том числе и тестирование) проводили люди, непосредственно не участвующие в их создании. Это не обязательно должны быть люди со стороны, из другой организации или компании. Это могут быть люди, входящие в команду разработки данного программного обеспечения, но не принимающие участие в создании того, что они проверяют. Тесты должны базироваться на требованиях Процесс верификации включает в себя процесс тестирования. Этот процесс является наиболее интенсивной частью процесса разработки. Тестирование, в свою очередь, делится на два процесса: определение теста, когда решается, что собой будет представлять тест, и выполнение теста. Обычно тестирование можно разделить на две части: неформальное тестирование, когда тестирование проводится самими разработчиками во время написания кода, и формальный процесс тестирования. Как правило, трудностей при создании неформальных тестов не возникает, поскольку сам программист знает, что и как нужно тестировать, но могут возникнуть сложности в определении тестовых процедур для формального тестирования. Стандарты DO178B/DO178С рекомендуют, чтобы тестовые процедуры были сфокусированы на требованиях. Каждая тестовая процедура должна адресоваться к определенному требованию или набору требований. Поэтому нельзя просто так добавить или убрать тестовую процедуру. В зависимости от того, на каких требованиях базируется тестирование, принято различить: Тестирование программно-аппаратной интеграции, когда верификация корректной работы ведется на целевом компьютере с целевым окружением. В этом случае идет проверка высокоуровневых требований. Тестирование программной интеграции, когда проверяется взаимодействие различных компонентов ПО. Цель этих тестов – проверка соответствия требованиям архитектуры и дизайна ПО. 51 Низкоуровневое тестирование, когда ПО проверяется на соответствие низкоуровневым требованиям. Как и какое тестирование проводить, должно быть описано в плане верификации. Для разработки надежного ПО можно ограничится только тестовыми процедурами, проверяющими высокоуровневые требования. Но если возникает необходимость поднять уровень надежности, то нужно создать и тесты, базирующиеся на низкоуровневых требованиях. Так же, как и для критического ПО, процесс тестирования должен проходить в соответствии с разработанным планом. Тестирование должно включать не только нормальное тесты, но и тесты на устойчивость. Для безопасного и надежного программного обеспечения тестирования с использованием тестов, которые проверяют работу программы только в нормальных условиях, недостаточно. Необходимо также использовать тесты, которые проверяют программу на устойчивость, или так называемые робастные тесты. Основная цель этих тестов – убедиться, что ПО работает корректно: при установке неправильных инициализационных значений для переменных; при инициализации в ненормальных условиях; при сбойной модели входных данных; при использовании счетчиков цикла за пределами их ограничений; в сбойных режимах или режимах отказа; при неправильной работе программного окружения; при работе в стрессе по времени, памяти и синхронизации с другими программами; при работе в любых других условиях, отличных от нормальных. Обязательно должна быть проведена проверка корректности работы механизма защиты и работа ПО в переходных состояниях, если о них указано в требованиях. Хорошая восприимчивость к сбоям является одной из важнейших характеристик надежного программного обеспечения. Программное обеспечение должно ломаться "правильно" Надежное и безопасное программное обеспечение должно быть спроектировано так, чтобы при возникновении критической ситуации оно ломалось ”правильно”. Это означает не только, что компьютер не должен зависать или выдавать ошибку операционной системы, если в программном обеспечении возник сбой. Гораздо важнее, чтобы при возникновении сбоя пользователь знал, что ПО перестало работать. Если ПО выдает некоторые значения, то очень важно, чтобы разница между сбойным значением и реальным была большой, чтобы можно было легко заметить, что это ПО сломалось и не работает. Например, пусть у вас есть программа, которая в соответствующем приборе участвует в измерении давления у человека. Если эта программа сломается, то какое значение она должна показывать: нулевое, последнее измеренное давление, выше или ниже реального давления? Надежное и безопасное ПО должно выдавать такое значение, чтобы человек, измеряющий давление, мог однозначно понять, что прибор сломан. Если в приведенном примере прибор 52 покажет ноль, то становится понятно, что он сломан и никакой большой проблемы здесь нет. Нужно просто использовать другой прибор. Серьезная проблема может возникнуть, если прибор при сбое покажет значение, близкое к реальному, но все же от него отличающееся. Это может привести к неправильным и даже опасным действиям, например к медикаментозному увеличению или уменьшению давления. Анализ тестового покрытия Анализ тестового покрытия является еще одним инструментом, помимо трассировки, базирующимся на требованиях к тестированию и позволяющим проверить, что код полностью соответствует заданным требованиям. Для критического ПО анализ тестового покрытия состоит из двух этапов: анализа покрытия тестов и анализа структурного покрытия. Первый из анализов проверяет, что для каждого требования, высокоуровневого или низкоуровневого, существуют свои нормальные и робастные тесты. В задачу анализа структурного покрытия входит нахождение кода, который не был протестирован ни одним из тестовых примеров. Как правило, для этого необходимо использовать специальные инструменты. Считается хорошим результатом, если структурное покрытие составляет 80%. То, что нельзя проверить инструментами, должно быть проверено анализом кода вручную. Если структуры кода не покрыты тестами, то это может происходить из-за: недостатков в тестовых процедурах; неадекватности требований; наличия ”мертвого”, не использованного кода; наличия деактивированного кода – кода, для которого есть требования, но он не выполняется при всех конфигурациях ПО. Для каждой ситуации должен быть план, что и как нужно делать. Обычно, если есть проблемы в тестовых процедурах или в требованиях, то их переделывают, мертвый код удаляют, а деактивированный код анализируют вручную. Для надежного ПО анализ тестового покрытия может производиться только для высокоуровневых требований. Можно также понизить требуемый процент покрытия кода или вообще не проводить структурное покрытие. Методика проведения анализа тестового покрытия должна быть оговорена на этапе планирования. Нельзя вносить изменения без соответствующего запроса При обнаружении ошибки в документе, требовании, коде или тестовой процедуре нельзя просто исправить ее. Неконтролируемое исправление может привести к еще большим проблемам, нежели первоначальная ошибка. Поэтом стандарты DO178B/DO178С требуют, чтобы все исправления осуществлялись только по запросу. Человек, обнаруживший ошибку, должен составить специальный рапорт на ошибку. Этот рапорт должен включать: уникальный идентификатор рапорта, чтобы за ним можно было проследить, описание проблемы, ее приоритет и возможные действия по ее устранению. Должно быть установлено, кто будет исправлять ошибку, и за какой срок. После исправления ошибки рапорт закрывается и проводится повторная верификация. Может оказаться так, что ошибся сам верификатор. В этом случае для закрытия рапорта нужно дать подробное объяснение, почему заявленная проблема не является ошибкой. Процесс сертификации может выйти на свою финальную стадию только если все рапорты об ошибках являются закрытыми. Весь механизм исправления ошибок прописывается в плане верификации. 53 При разработке надежного ПО также очень важно, чтобы исправление ошибок во всех артефактах жизненного цикла было под контролем. Во время процесса планирования необходимо определить приемлемый механизм исправления ошибок. Любая другая команда, используя ваши артефакты, может воспроизвести ваш продукт Если программный продукт может быть воспроизведен только один раз или только определенной группой людей, то этот продукт не может считаться ни надежным, ни тем более безопасным. Весь процесс разработки необходимо организовать так, чтобы создаваемое ПО могло быть воспроизведено другими людьми. Прежде всего это касается качества документации. Документация разрабатываемого ПО должна быть такой, чтобы люди, не имеющие отношения к вашему проекту, могли понять, какие функции и как выполняет ваше ПО, что представляет собой весь процесс его разработки, какое программно-аппаратное окружение для него используется и как его можно заново воспроизвести. Для надежного и безопасного ПО должны быть созданы документы, в которых содержится: общий обзор программного обеспечения с описанием того, что оно делает; описание функций работы ПО и их влияние на надежность; описание модели жизненного цикла разработки и всех процессов, в него входящих; описание всех артефактов жизненного цикла; полное описание программно-аппаратного окружения; полное описание конфигурации программного продукта: версия, дата создания, описание всех компонентов, которые в него включены или используются, и так далее. цикла; информацию о том, кто за что отвечал на всем протяжении жизненного все планы, включая планы разработки, верификации, обеспечения качества, план управления конфигурации; ссылки на все стандарты; описание всех процедур верификации и валидации; записи всех верификационных действий и их результатов. Следует также иметь в виду и человеческий фактор. Может возникнуть ситуация, когда какойто ключевой разработчик заболеет, по той или иной причине уйдет из команды разработчиков или вообще покинет компанию. Нужно организовать процесс разработки таким образом, чтобы это не повлияло или незначительно повлияло на весь процесс разработки и сроки его выполнения. Для этого рекомендуется весь процесс делать более формальным и менее зависимым от конкретных людей. 3.2 Функциональная методология IDEF0 54 Наиболее популярной методологией IDEF является методология IDEF0. Методологию IDEF0 можно считать следующим этапом развития хорошо известного графического языка описания функциональных систем SADT (Structured Analysis and Design Technique – Техника структурного анализа и дизайна). Исторически IDEF0 как стандарт был разработан в 1981 году в рамках обширной программы автоматизации промышленных предприятий, которая носила обозначение ICAM (Integrated Computer Aided Manufacturing). Семейство стандартов IDEF унаследовало свое обозначение от названия этой программы (IDEF=Icam DEFinition), и последняя его редакция была выпущена в декабре 1993 года Национальным Институтом по Стандартам и Технологиям США (NIST). В России приняты официальные рекомендации по применению методологии IDEEF0. Целью методологии является построение функциональной схемы исследуемой системы, описывающей все необходимые процессы с точностью, достаточной для однозначного моделирования деятельности системы. Другими словами, в IDEF0 моделируемая система представляется как совокупность взаимосвязанных работ (функций, активностей). Методология IDEF0 получила столь широкое распространение в бизнес–моделировании потому, что эта методология легко представляет такие системные характеристики, как управление, обратная связь, исполнители. Кроме того, методология IDEF0 имеет развитые процедуры поддержки коллективной работы. В основе методологии лежат четыре основных понятия: функциональный блок, дуга (стрелка), декомпозиция, глоссарий. Функциональный блок, или работа (Activity Box) представляет собой некоторую конкретную функцию ( работу) в рамках рассматриваемой системы. Блок должен иметь название в глагольном наклонении (например, "Проверить документ" или "Проверка документа"). На диаграмме функциональный блок изображается прямоугольником (рисунок 3.1). Каждая из четырех сторон функционального блока имеет свое определенное значение (роль) и определяет тип интерфейса, т. е. способ взаимодействия дуги с блоком: верхняя сторона имеет значение "Управление" (Control); левая сторона имеет значение "Вход" (Input); правая сторона имеет значение "Выход (Output); нижняя сторона имеет значение "Механизм" (Mechanism). Дуга (Arrow) отображает элемент системы, который обрабатывается функциональным блоком или оказывает иное влияние на функцию, представленную данным функциональным блоком. Интерфейсные дуги часто называют потоками или стрелками. С помощью дуг отображают различные объекты, которые передаются между блоками, обрабатываются блоками, определяют правила обработки и механизмы обработки . Такими объектами могут быть элементы реального мира (детали, вагоны , сотрудники и т.д.) или потоки данных и информации (документы, данные, инструкции и т.д.). Стрелки снабжаются надписями – названиями. В зависимости от того , к какой из сторон функционального блока подходит данная интерфейсная дуга, она носит название "входящей", "исходящей", "управляющей", "механизмом" или вызовом. 55 Рисунок 3.1 – Функциональный блок В IDEF0 различают пять типов стрелок. Вход (Input) – материальные объекты или информация, которые используются или преобразуются работой для получения результата (выхода). Допускается, что блок может не иметь ни одной стрелки входа. При описании технологических процессов не возникает проблем определения входов. Вход – это нечто, что перерабатывается в блоке для получения результата. При моделировании информационной системы, когда стрелками являются не физические объекты, а данные, определение входа может вызвать трудности. Например, чтобы показать переработку данных блоком, целесообразно на входе указать "Документ", а на выходе – "Заполненный документ". Например, не может быть входом блока " Прием экзамена" стрелка "Студент", а выходом – стрелка "Экзаменационная ведомость", т. к. студент не перерабатывается в ведомость. В данном примере можно использовать входную стрелку "Не аттестованный студент" и выходную стрелку "Аттестованный студент". Очень часто сложно определить, являются ли данные входом или управлением. В этом случае подсказкой может служить информация о том, перерабатываются /изменяются ли данные в блоке или нет. Если изменяются, то, скорее всего, это вход, если нет – управление. Например, задание на курсовой проект является управлением, а не входом. Управление (Control) – правила, стратегии, процедуры, стандарты, ограничения на бюджет и время, которыми руководствуется работа. Каждая работа должна иметь хотя бы одну стрелку управления. Управление влияет на работу, но не преобразуется работой. В случае возникновения неопределенности в статусе стрелки (управление или вход) рекомендуется рисовать стрелку управления. Выход (Output) – материальный объект или информация, которые производятся работой. Каждая работа должна иметь хотя бы одну стрелку выхода. Работа без результата не имеет смысла и не должна моделироваться. Механизм (Mechanism) – ресурсы, которые выполняют работу, например персонал предприятия, станки, устройства и т. д. По усмотрению аналитика стрелки механизма могут не изображаться в модели. Вызов (Call) – специальная стрелка , указывающая на другую модель работы. Стрелка вызова используется при расщеплении модели и указывает, что некоторая работа представлена отдельной моделью. Расщепление моделей необходимо для коллективной работы над моделью. Руководитель проекта может создать декомпозицию верхнего уровня и провести расщепление модели на отдельные модели. Аналитики работают над отдельными моделями, а затем сливают отдельные модели в единую модель. Отдельная ветвь модели может быть отщеплена для использования в качестве независимой модели. Таким образом, любой функциональный блок по требованиям стандарта должен иметь, по крайней мере, одну управляющую дугу и одну исходящую. То есть каждый процесс должен происходить по каким-то правилам (отображаемым управляющей дугой) и должен выдавать некоторый результат (выходящая дуга), иначе его рассмотрение не имеет никакого смысла. 56 Декомпозиция (Decomposition) является основным понятием стандарта IDEF0. Принцип декомпозиции применяется при разбиении сложного процесса на составляющие его функции. Декомпозиция позволяет постепенно и структурировано представлять модель системы в виде иерархической структуры отдельных диаграмм, что делает ее менее перегруженной и легко усваиваемой. Глоссарий (Glossary) – это набор соответствующих определений, ключевых слов, повествовательных изложений и т.д., которые характеризуют объект, отображенный данным элементом. Этот набор является описанием сущности данного элемента. Глоссарий дополняет наглядный графический язык, снабжая диаграммы необходимой дополнительной информацией. Модель в методологии IDEF0 – это совокупность иерархически упорядоченных и взаимосвязанных диаграмм . Каждая диаграмма является единицей описания системы и располагается на отдельном листе. Модель может содержать четыре типа диаграмм: 1. Контекстная диаграмма, которая представляет всю систему как один блок и показывает контекст системы, т. е. связь системы с внешним миром. Модель может иметь только одну контекстную диаграмму. 2. Диаграммы декомпозиции, которые получаются в результате разбиения контекстной диаграммы на отдельные активности. Такой процесс называется функциональной декомпозицией, а диаграммы, получившиеся в результате декомпозиции, называются диаграммами декомпозиции. После декомпозиции контекстной диаграммы производится декомпозиция каждой получившейся диаграммы и т. д. Декомпозиция продолжается до достижения нужного уровня подробности описания. После каждого сеанса декомпозиции проводятся сеансы экспертизы – эксперты предметной области проверяют соответствие реальных бизнес–процессов созданным диаграммам. Найденные несоответствия исправляются , и только после прохождения экспертизы без замечаний можно приступать к следующему сеансу декомпозиции. Так достигается соответствие модели реальным бизнес–процессам на каждом уровне модели. Синтаксис описания системы в целом и каждого ее фрагмента одинаков во всей модели. 3. Диаграммы дерева узлов показывают иерархическую зависимость работ. То есть, в виде дерева показывается, какие активности получились в результате декомпозиции каждой активности. Диаграмм деревьев узлов может быть в модели несколько, поскольку дерево может быть построено на различную глубину и начиная с любой диаграммы (не обязательно с контекстной). 4. Диаграммы только для экспозиции (FEO – for exposition only) строятся для иллюстрации альтернативной точки зрения, для хранения старых версий. FEO – это просто картинка. Дело в том, что методология не поддерживает альтернативные варианты декомпозиции. Если необходимо хоть как-то сохранить альтернативный вариант декомпозиции, то применяют диаграмму только для экспозиции. Рассмотрим подробнее различные виды диаграмм. Модель IDEF0 всегда начинается с представления системы как единого целого – одной активности с дугами, простирающимися за пределы рассматриваемой области. Такая диаграмма с одной активностью называется контекстной диаграммой. Дуги контекстной диаграммы должны описывать все основные связи моделируемой системы с внешним миром. Методология IDEF0 подразумевает, что модель является не просто совокупностью диаграмм, а содержит всю необходимую информацию о моделируемой области. Информация о модели 57 задается в свойствах модели. В BPWin информация задается в диалоге свойств модели (Model Properties). В общих свойствах (General) указываются имя модели, название проекта, автор модели временные рамки модели (Time Frame) – AS-IS и ТО-ВЕ. Обычно сначала строится модель существующей организации работы – AS-IS (как есть). Анализ функциональной модели позволяет понять, где находятся наиболее слабые места, в чем будут состоять преимущества новых бизнес– процессов и насколько глубоким изменениям подвергнется существующая структура организации бизнеса. Детализация бизнес–процессов позволяет выявить недостатки организации даже там, где функциональность на первый взгляд кажется очевидной. Найденные в модели AS-IS недостатки можно исправить при создании модели ТО-ВЕ (как будет) – модели новой организации бизнес–процессов. Иногда текущая AS-IS и будущая ТО-ВЕ модели различаются очень сильно, так что переход от начального к конечному состоянию становится неочевидным . В этом случае необходима третья модель, описывающая процесс перехода от начального к конечному состоянию системы, поскольку такой переход – это тоже бизнес– процесс. Цель моделирования (Purpose) определяется из ответов на следующие вопросы: Почему этот процесс должен быть смоделирован? Что должна показывать модель? Что может получить клиент? Точка зрения (Viewpoint) – это перспектива, с которой наблюдалась система при построении модели. Хотя при построении модели учитываются мнения различных людей, все они должны придерживаться единой точки зрения на модель. Точка зрения должна соответствовать цели и границам моделирования. Как правило, выбирается точка зрения человека, ответственного за моделируемую работу в целом. Даются также определение модели (Definition) и описание области действия модели (Scope). Указываются источники получения данных о модели (Source), например, "Опрос экспертов предметной области и анализ документации". Статус модели (Status) – это рабочая версия (новая модель, не прошедшая экспертиз) – WORKING, черновой вариант (модель прошла первичную экспертизу) – DRAFT, рекомендовано (прошла экспертизу) – RECOM-MENDED, публикация (окончательный вариант) – PUBLICATION. Каждая активность может быть подвергнута декомпозиции на другой – "дочерней" диаграмме (Child Diagram). Каждая диаграмма нижнего уровня показывает "внутреннее" строение активности на родительской диаграмме (Parent Diagram). Каждая из активностей дочерней диаграммы может быть далее детализирована путем аналогичной декомпозиции. В каждом случае декомпозиции функционального блока все интерфейсные дуги, входящие в данный блок или исходящие из него, фиксируются на дочерней диаграмме. Этим достигается структурная целостность IDEF0-модели. Чтобы сделать диаграммы удобочитаемыми, в стандарте IDEF0 приняты ограничения сложности: на диаграмме может быть от трех до шести активностей (в BPwin – от 2 до 8), при этом количество подходящих к одной активности и выходящих из одной активности дуг предполагается не более четырех. Работы на диаграммах декомпозиции обычно располагаются в так называемом порядке доминирования – по диагонали от левого верхнего угла к правому нижнему. Согласно этому принципу расположения в левом верхнем углу располагается самая важная работа или работа, выполняемая по времени первой. Далее вправо вниз располагаются менее важные или выполняемые позже работы. Такое расположение облегчает чтение диаграмм, кроме того, на нем основывается понятие взаимосвязей работ. 58 Все активности модели нумеруются. Номер состоит из префикса и числа. Может быть использован префикс любой длины, но обычно используют префикс А. Контекстная активность имеет номер А0. Активности, полученные в результате декомпозиции контекстной активности номера А1, А2, A3 и т. д. Работы декомпозиции нижнего уровня имеют номер родительской активности и очередной порядковый номер, например активности декомпозиции A3 будут иметь номера А31, А32, АЗЗ, А34 и т. д. Активности образуют иерархию, где каждая активность может иметь одну родительскую и несколько дочерних работ, образуя дерево. Такое дерево называют деревом узлов, а вышеописанную нумерацию – нумерацией по узлам. Диаграммы IDEF0 имеют двойную нумерацию. Во-первых, диаграммы имеют номера по узлу. Контекстная диаграмма всегда имеет номер А-0, декомпозиция контекстной диаграммы – номер А0, остальные диаграммы декомпозиции – номера по соответствующему узлу (например, Al, A2, А21, А213 и т. д.). BPwin автоматически поддерживает нумерацию по узлам, т. е. при проведении декомпозиции создается новая диаграмма и ей автоматически присваивается соответствующий номер. Чтобы отличать различные версии одной и той же диаграммы, используется специальный номер – C-number, который должен присваиваться автором модели вручную. C-number – это произвольная строка, но рекомендуется придерживаться стандарта, когда номер состоит из буквенного префикса и порядкового номера, причем, в качестве префикса используются инициалы автора диаграммы, а порядковый номер отслеживается автором вручную, например GVI021. Если активность не повергалась декомпозиции, то левый верхний угол прямоугольника активности автоматически перечеркивается. Стрелки на контекстной диаграмме служат для описания взаимодействия системы с окружающим миром. Они могут начинаться у границы диаграммы и заканчиваться у работы, или наоборот. Такие стрелки называются граничными. Граничные стрелки мигрируют (переносятся) из родительской диаграммы в дочернюю диаграмму. Границы дочерней диаграммы соответствуют границам декомпозируемой активности. Поэтому входные стрелки располагаются на левой границе диаграммы декомпозиции и т. п. Для большего удобства граничные стрелки могут снабжаться так называемыми ICOM-кодами. ICOM (аббревиатура от Input, Control, Output и Mechanism) – коды, предназначенные для идентификации граничных стрелок. Код ICOM содержит префикс, соответствующий типу стрелки (I, С, О или М), и порядковый номер. Граничные стрелки необходимо соединить с соответствующими входами, выходами и т. п. активностей диаграммы декомпозиции. Стрелки, соединяющие активности на диаграмме, называются внутренними. В IDEF0 различают пять типов связей работ. Связь по входу (output-input), когда стрелка выхода вышестоящей работы (далее – просто выход) направляется на вход нижестоящей работы (рисунок 3.2). На рисунках 3.5 – 3.6 в основном показаны только рассматриваемые связи. Рисунок 3.2 - Связь по входу 59 Связь по управлению (output-control), когда выход вышестоящей работы направляется на управление нижестоящей (рис. 3.3). Связь по управлению показывает доминирование вышестоящей работы. Рисунок 3.3 - Связь по управлению Обратная связь по входу (output-input feedback), когда выход нижестоящей работы направляется на вход вышестоящей (рисунок 3.4). Такая связь, как правило, используется для описания циклов. Рисунок 3.4 - Обратная связь по входу Обратная связь по управлению (output-control feedback), когда выход нижестоящей работы направляется на управление вышестоящей (рисунок 3.5). Обратная связь по управлению часто свидетельствует об эффективном управлении бизнес – процессами. Связь выход-механизм (output-mechanism), когда выход одной работы направляется на механизм другой. Эта взаимосвязь используется реже остальных и показывает, что одна работа подготавливает ресурсы, необходимые для проведения другой работы (рисунок 3.6). Рисунок 3.5 - Обратная связь по управлению 60 Рисунок 3.6 - Связь выход-механизм Простейшим и наиболее распространенным видом стрелок является явная стрелка, которая имеет источником одну-единственную активность и назначением тоже одну -единственную активность . Одни и те же данные или объекты, порожденные одной активностью, могут использоваться сразу в нескольких других активностях. С другой стороны, стрелки, порожденные в разных активностях, могут представлять собой одинаковые или однородные данные или объекты, которые в дальнейшем используются или перерабатываются в одном месте. Для моделирования таких ситуаций в IDEF0 используются разветвляющиеся и сливающиеся стрелки. Смысл разветвляющихся и сливающихся стрелок передается именованием каждой ветви стрелок. Существуют определенные правила именования таких стрелок. Рассмотрим их на примере разветвляющихся стрелок. Если стрелка именована до разветвления, а после разветвления ни одна из ветвей не именована, то подразумевается, что каждая ветвь моделирует те же данные или объекты, что и ветвь до разветвления. Если стрелка именована до разветвления, а после разветвления какая-либо из ветвей тоже именована, то подразумевается, что эти ветви соответствуют именованию. Если при этом какая-либо ветвь после разветвления осталась неименованной, то подразумевается, что она моделирует те же данные или объекты, что и ветвь до разветвления. Недопустима ситуация, когда стрелка до разветвления не именована, а после разветвления не именована какая-либо из ветвей. Правила именования сливающихся стрелок полностью аналогичны – ошибкой будет считаться стрелка, которая после слияния не именована, а до слияния не именована какая-либо из ее ветвей. Для именования отдельной ветви разветвляющихся и сливающихся стрелок следует выделить на диаграмме только одну ветвь, после чего вызвать редактор имени и присвоить имя стрелке. Это имя будет соответствовать только выделенной ветви. Иногда отдельные интерфейсные дуги высшего уровня не имеет смысла продолжать рассматривать на диаграммах нижнего уровня , или наоборот – отдельные дуги нижнего уровня отражать на диаграммах более высоких уровней – это будет только перегружать диаграммы и делать их сложными для восприятия. Для решения подобных задач в стандарте IDEF0 предусмотрено понятие туннелирования. Вновь созданные на диаграмме декомпозиции граничные стрелки изображаются в квадратных скобках и автоматически не появляются на диаграмме верхнего уровня (рисунок 3.7). Рисунок 3.7 - Неразрешенная (unresolved) стрелка Можно разрешить миграцию новой стрелки на диаграмму верхнего уровня или не разрешить такую миграцию. В последнем случае говорят, что стрелка будет туннелирована. В BPwin для этого нужно щелкнуть правой кнопкой мыши по квадратным скобкам граничной стрелки и в 61 контекстном меню выбрать команду Arrow Tunnel. Появляется диалог Border Arrow Editor. Если щелкнуть по кнопке Resolve Border Arrow, стрелка мигрирует на диаграмму верхнего уровня, если по кнопке Change To Tunnel – стрелка будет туннелирована и не попадет на другую диаграмму. Туннельная стрелка изображается с круглыми скобками на конце. Туннелирование может быть применено для изображения малозначимых стрелок. Если на какой-либо диаграмме нижнего уровня необходимо изобразить малозначимые данные или объекты, которые нецелесообразно отображать на диаграммах вышестоящего уровня, то следует туннелировать стрелки на самом нижнем уровне. Такое туннелирование называется туннель "не-в-родительской-диаграмме". Другим примером туннелирования может быть ситуация, когда стрелка механизма мигрирует с верхнего уровня на нижний, причем на нижнем уровне этот механизм используется одинаково во всех работах без исключения. В этом случае стрелка механизма на нижнем уровне может быть удалена, после чего на родительской диаграмме она может быть туннелирована, острие стрелки на родительской диаграмме будет изображено в круглых скобках. В комментарии к стрелке или в словаре можно указать, что механизм будет использоваться во всех работах дочерней диаграммы декомпозиции. Такое туннелирование называется туннель "не-в-дочерней-диаграмме". Стандарт IDEF0 содержит набор процедур, позволяющих разрабатывать и согласовывать модель большой группой людей , принадлежащих к разным областям деятельности моделируемой системы. Обычно процесс разработки является итеративным и состоит из следующих условных этапов: 1. Создание модели группой специалистов, относящихся к различным сферам деятельности предприятия . Эта группа в терминах IDEF0 называется авторами (Authors). Построение первоначальной модели является динамическим процессом, в течение которого авторы опрашивают компетентных лиц о структуре различных процессов, создавая модели деятельности подразделений. При этом их интересуют ответы на следующие вопросы: Что поступает в подразделение "на входе"? Какие функции подразделения? и в какой последовательности выполняются в рамках Кто является ответственным за выполнение каждой из функций? Чем руководствуется исполнитель при выполнении каждой из функций? Что является результатом работы подразделения (на выходе)? 2. На основе имеющихся положений, документов и результатов опросов создается черновик (Model Draft) модели. 3. Распространение черновика для рассмотрения, согласований и комментариев. На этой стадии происходит обсуждение черновика модели с широким кругом компетентных лиц (в терминах IDEF0 – читателей) на предприятии. При этом каждая из диаграмм черновой модели письменно критикуется и комментируется, а затем передается автору. Автор, в свою очередь, также письменно соглашается с критикой или отвергает ее с изложением логики принятия решения и вновь возвращает откорректированный черновик для дальнейшего рассмотрения. Этот цикл продолжается до тех пор, пока авторы и читатели не придут к единому мнению. 62 4. Официальное утверждение модели. Утверждение согласованной модели происходит руководителем рабочей группы в том случае, если у авторов модели и читателей отсутствуют разногласия по поводу ее адекватности. Окончательная модель представляет собой согласованное представление предприятии (системе) с заданной точки зрения и для заданной цели. Наглядность графического языка IDEF0 делает модель вполне читаемой и для лиц, которые не принимали участия в проекте ее создания, а также эффективной для проведения показов и презентаций. В дальнейшем на базе построенной модели могут быть организованы новые проекты, нацеленные на производство изменений в модели. 3.3 Методология DFD Целью методологии является построение модели рассматриваемой системы в виде диаграммы потоков данных (Data Flow Diagram – DFD). Диаграммы потоков данных предназначены прежде всего для описания документооборота и обработки информации, хотя допускают и представление других объектов. При создании диаграммы потоков данных используются четыре основных понятия: потоки данных; процессы (работы) преобразования входных потоков данных в выходные; внешние сущности; накопители данных (хранилища). Потоки данных являются абстракциями, использующимися для моделирования передачи информации (или физических компонент) из одной части системы в другую. Потоки на диаграммах изображаются именованными стрелками, ориентация которых указывает направление движения информации. Процессы ( работы) служат для преобразования входных потоков данных в выходные. Имя процесса должно содержать глагол в неопределенной форме с последующим дополнением (например, «получить документы по отгрузке продукции»). Каждый процесс имеет уникальный номер для ссылок на него внутри диаграммы, который может использоваться совместно с номером диаграммы для получения уникального индекса процесса во всей модели. Хранилище (накопитель ) данных моделирует данные, которые будут сохраняться в памяти между процессами. Информация, которую содержит хранилище, может использоваться в любое время после ее получения, при этом данные могут выбираться в любом порядке. Имя хранилища должно определять его содержимое и быть существительным. Внешняя сущность представляет собой материальный объект вне контекста системы, являющейся источником или приемником данных. Ее имя должно содержать существительное, например, « склад товаров ». Предполагается, что объекты, представленные как внешние сущности, не должны участвовать ни в какой обработке. Кроме основных элементов, в состав DFD входят словари данных и миниспецификации. Словари данных являются каталогами всех элементов данных, присутствующих в DFD, включая потоки данных, хранилища и процессы, а также все их атрибуты. Миниспецификации обработки – описывают DFD-процессы нижнего уровня. Фактически миниспецификации представляют собой алгоритмы описания задач, выполняемых процессами: множество всех миниспецификаций является полной спецификацией системы. 63 Диаграммы потоков данных строятся в виде иерархии. Сначала строится контекстная диаграмма. При проектировании относительно простых систем строится единственная контекстная диаграмма со звездообразной топологией, в центре которой находится так называемый главный процесс, соединенный с приемниками и источниками информации, посредством которых с системой взаимодействуют пользователи и другие внешние системы. Перед построением контекстной DFD необходимо проанализировать внешние события (внешние сущности), оказывающие влияние на функционирование системы. Количество потоков на контекстной диаграмме должно быть по возможности небольшим , поскольку каждый из них может быть в дальнейшем разбит на несколько потоков на следующих уровнях диаграммы. Для сложных систем (признаками сложности могут быть наличие большого количества внешних сущностей (десять и более), распределенная природа системы или ее многофункциональность) строится иерархия контекстных диаграмм. При этом контекстная диаграмма верхнего уровня содержит не единственный главный процесс, а набор подсистем, соединенных потоками данных. Контекстные диаграммы следующего уровня детализируют контекст и структуру подсистем. Для проверки контекстной диаграммы можно составить список событий. Список событий должен состоять из описаний действий внешних сущностей ( событий ) и соответствующих реакций системы на события. Каждое событие должно соответствовать одному или более потокам данных: входные потоки интерпретируются как воздействия, а выходные потоки – как реакции системы на входные потоки. Каждый процесс на DFD, в свою очередь, может быть детализирован при помощи DFD или (если процесс элементарный) спецификации. Спецификация процесса должна формулировать его основные функции таким образом, чтобы в дальнейшем специалист, выполняющий реализацию проекта, смог выполнить их или разработать соответствующую программу. Спецификация является конечной вершиной иерархии DFD. Решение о завершении детализации процесса и использовании спецификации принимается аналитиком исходя из следующих критериев: наличия у процесса относительно небольшого количества входных и выходных потоков данных (2-3 потока); возможности описания последовательного алгоритма; преобразования данных процессов в виде выполнения процессом единственной логической функции преобразования входной информации в выходную; возможности описания логики процесса при помощи спецификации небольшого объема (не более 20-30 строк). В качестве языка спецификаций обычно используются структурированный естественный язык или псевдокод. В методологии DFD используются две нотации: Йодана-Де Марко (Yourdan) и Гейна-Сарсона (Gane-Sarson) – таблица 3.1. Следует отметить, что в BPwin формально используется нотация Гейна-Сарсона, но с рядом отступлений: отсутствуют миниспецификации, отличается изображение функций, контекстная диаграмма не может содержать подсистемы. Сравнивая методологии DFD и IDEF0, можно отметить, что в методологии DFD, кроме расширения изобразительных возможностей диаграмм (за счет хранилищ данных ), изменяются правила интерфейсов для стрелок: стрелки могут входить и выходить с любой стороны блока. 64 Таблица 1.1 - Элементы методологии DFD в нотациях Гейна-Сарсона и Йодана-Де Марко 3.4 Методология IDEF3 IDEF3 является стандартом документирования технологических процессов, происходящих на предприятии, и предоставляет инструментарий для наглядного исследования и моделирования их сценариев. Сценарием (Scenario) называется описание последовательности изменений свойств объекта в рамках рассматриваемого процесса (например, описание последовательности этапов обработки детали в цехе и изменение её свойств после прохождения каждого этапа). Исполнение каждого сценария сопровождается соответствующим документооборотом, который состоит из двух основных потоков: документов, определяющих структуру и последовательность процесса (технологические карты, стандарты и т.д.), и документов , отображающих ход его выполнения (результаты тестов и экспертиз, отчеты о браке, и т.д.). Для эффективного управления любым процессом, необходимо иметь детальное представление об его сценарии и структуре сопутствующего документооборота. Средства документирования и моделирования IDEF3 позволяют выполнять следующие задачи: 1. Документировать данные о технологии процесса. 2. Определять и анализировать точки влияния потоков документооборота на сценарий технологических процессов. сопутствующего 3. Определять ситуации, в которых требуется принятие решения, влияющего на жизненный цикл процесса, например, изменение конструктивных, технологических или эксплуатационных свойств конечного продукта. 4. Содействовать принятию технологических процессов. оптимальных решений при реорганизации 5. Разрабатывать имитационные модели технологических процессов, по принципу "КАК БУДЕТ, ЕСЛИ..." Такая возможность существует при использовании, например, системы имитационного моделирования ARENA. 65 Существуют два типа диаграмм в стандарте IDEF3, представляющих описание одного и того же сценария технологического процесса в разных ракурсах. Диаграммы, относящиеся к первому типу, называются диаграммами потокового описания процесса (Process Flow Description Diagrams, PFDD), а ко второму – диаграммами сети изменения состояний объектов (Object State Transition Network, OSTN). Рассмотрим пример. Предположим, требуется описать процесс окраски детали в производственном цехе на предприятии. С помощью диаграмм PFDD документируется последовательность и описание стадий обработки детали в рамках исследуемого технологического процесса. Диаграммы OSTN используются для иллюстрации трансформаций детали, которые происходят на каждой стадии обработки. На следующем примере опишем, как графические средства IDEF3 позволяют документировать вышеуказанный производственный процесс окраски детали. В целом, этот процесс состоит непосредственно из самой окраски, производимой на специальном оборудовании и этапа контроля ее качества, который определяет, нужно ли деталь окрасить заново (в случае несоответствия стандартам и выявления брака) или отправить ее в дальнейшую обработку. Рисунок 3.8 - Пример PFDD диаграммы На рисунке 3.8 изображена диаграмма PFDD, являющаяся графическим отображением сценария обработки детали. Прямоугольники на диаграмме PFDD называются функциональными элементами или элементами поведения (Unit of Behavior, UOB)1 и обозначают событие, стадию процесса или принятие решения . Каждый UOB имеет свое имя, отображаемое в глагольном наклонении, и уникальный номер. Этот номер не используется вновь даже в том случае, если в процессе построения модели действие удаляется. В диаграммах IDEF3 номер действия, полученного в результате декомпозиции, обычно предваряется номером его родителя (рисунок 3.9). Рисунок 3.9 - Изображение и нумерация действия в диаграмме IDEF3 Существенные взаимоотношения между действиями изображаются с помощью связей. Все связи в IDEF3 являются однонаправленными, и хотя стрелка может начинаться или заканчиваться на любой стороне блока, обозначающего действие, диаграммы IDEF3 обычно организуются слева направо таким образом, что стрелки начинаются на правой и заканчиваются на левой стороне блоков. В таблице 3.2 приведены три возможных типа связей. Стандарт предусматривает и другие типы стрелок, но они малоприменимы и не поддерживаются CASE-системами. 66 Таблица 3.2 - Типы связей IDEF3 Связь типа "временное предшествование" показывает, что исходное действие должно полностью завершиться, прежде чем начнется выполнение конечного действия. Связь типа "объектный поток" используется в том случае, когда некоторый объект, являющийся результатом выполнения исходного действия, необходим для выполнения конечного действия. Обозначение такой связи отличается от связи временного предшествования двойной стрелкой. Наименования потоковых связей должны четко идентифицировать объект , который передается с их помощью. Временная семантика объектных связей аналогична связям предшествования , это означает , что порождающее объектную связь исходное действие должно завершиться, прежде чем конечное действие может начать выполняться. Связь типа "нечеткое отношение" используется для выделения отношений между действиями, которые невозможно описать с использованием связей предшествования или объектных связей. Обычно эти связи указывают, что между объектам существуют некоторые отношения, но на момент описания процесса они не определены. Объект, обозначенный на рисунке 3.8 как J1, называется перекрестком (Junction). Перекрестки используются для отображения логики взаимодействия стрелок (потоков) при слиянии и разветвлении или для отображения множества событий, которые могут или должны быть завершены перед началом следующей работы. Различают перекрестки для слияния (Fan-in Junction) и перекрестки для разветвления (Fan-out Junction) стрелок. Перекресток не может использоваться одновременно для слияния и для разветвления. При внесении перекрестка в диаграмму необходимо указать тип перекрестка. Классификация возможных типов перекрестков приведена в таблице 3.3. Таблица 3.3 – Типы перекрестков 67 Все перекрестки в PFDD диаграмме нумеруются, каждый номер имеет префикс "J". Сценарий, отображаемый на диаграмме, можно описать в следующем виде. Деталь поступает в окрасочный цех, подготовленной к окраске. В процессе окраски наносится один слой эмали при высокой температуре. После этого производится сушка детали, после которой начинается этап проверки качества нанесенного слоя. Если тест подтверждает недостаточное качество нанесенного слоя (недостаточную толщину, неоднородность и т.д.), то деталь заново пропускается через цех окраски. Если деталь успешно проходит контроль качества, то она отправляется в следующий цех для дальнейшей обработки. Описания процессов могут состоять из нескольких сценариев и содержать как диаграммы PFDD, так и OSTN. Для обозначения отношений и связей между UOB различных уровней PFDD и OSTN диаграмм и разных сценариев в IDEF3 используются специальные ссылки (Referents). Ссылки могут использоваться: для обращения к ранее определенному функциональному модулю UOB без повторения его описания; для передачи управления или индикации наличия циклических действий при выполнении процесса; организации связи между диаграммами описания процесса PFDD и OSTN диаграммами. Соответственно, выделяют следующие типы ссылок: GOTO – циклический переход (в повторяющейся последовательности UOW), возможно, на текущей диаграмме, но не обязательно. Если все UOW цикла присутствуют на текущей диаграмме, цикл может также изображаться стрелкой, возвращающейся на стартовую UOW. GOTO может ссылаться на перекресток. UOB – экземпляр другого, ранее определенного UOB, выполняется в определенной точке. Например, UOB "Контроль качества" может быть использован в процессе "Изготовление редуктора" несколько раз, после каждой единичной операции. 68 SCENARIO – название сценария. Эта ссылка означает, что должна быть произведена активизация всех декомпозиций указанного сценария. TS (Transition Schematic) – переход на схему. Это ссылка на соответствующую диаграмму, т. е. процесс, на который ссылаются, должен быть инициализирован. NOTE (примечание) используется для документирования информации, относящейся к какимлибо графическим объектам на диаграмме. Элемент «примечание» может использоваться как в диаграммах описания процесса, так и объектных диаграммах OSTN. Этот элемент может быть применен к функциональному элементу UOW, перекрестку, связи, объекту или ссылке. Отметим, что в BPwin используются немного другие ссылки. Методология IDEF3 определяет два вида ссылок по способу запуска. Ссылка "Вызвать и продолжить" (Call and Continue Referent) указывает, что элемент, указанный в ссылке, должен быть активизирован до завершения выполнения действия модулем, к которому относится ссылка. Ссылка "Вызвать и ждать" (Call and Wait Referent), указывает, что элемент, указанный в ссылке, должен начать и закончить выполнение действия до завершения действия модулем, к которому относится ссылка. Графические обозначения ссылок приведены на рисунке 3.10. В основном поле символа ссылки указывается её тип (Referent Type) "UOB", "SCENARIO", "TS" или "GOTO" и через дробь "Label" – уникальное наименование блока, сценария, схемы или функции узла, на который указывает ссылка. В поле "Locator" указывается уникальный идентификатор элемента, указанного в ссылке. Пример использования ссылок показан на рисунке 3.11 Рисунок 3.10 - Графическое обозначение ссылок Рисунок 3.11 - Примеры использования ссылок Каждый функциональный блок UOB может иметь последовательность декомпозиций, и, следовательно, может быть детализирован с любой необходимой точностью. Под декомпозицией мы понимаем представление каждого UOB с помощью отдельной IDEF3 диаграммы. Например, мы можем декомпозировать UOB "Окрасить Деталь", представив его 69 отдельным процессом и построив для него свою PFDD диаграмму. При этом эта диаграмма будет называться дочерней, по отношению к изображенной на рисунке 3.8, а та, соответственно, родительской. Номера UOB дочерних диаграмм имеют сквозную нумерацию, т.е., если родительский UOB имеет номер "1", то блоки UOB на его декомпозиции будут соответственно иметь номера "1.1", "1.2" и т.д. Применение принципа декомпозиции в IDEF3 позволяет структурировано описывать процессы с любым требуемым уровнем детализации. На рисунке 3.12 приведен пример декомпозиции модулей (UOB) и принцип формирования их номеров. Для наглядности все модули представлены на одном рисунке, но в IDEF3 они отображаются в трех диаграммах. Методология IDEF3 позволяет декомпозировать работу многократно, т. е. работа может иметь множество дочерних работ. Возможность множественной декомпозиции отражается в нумерации работ: номер работы состоит из номера родительской работы, номера декомпозиции и номера работы на текущей диаграмме. На рисунке 3.13 представлен пример двух вариантов декомпозиции родительского модуля. Рисунок 3.12 - Декомпозиция функциональных блоков 70 Рисунок 3.13 - Пример двух вариантов декомпозиции модуля Если диаграммы PFDD описывают технологический процесс "с точки зрения наблюдателя ", то другой класс диаграмм OSTN – диаграммы сети изменения состояний объектов (не поддерживаются в BPwin) позволяет рассматривать тот же самый процесс "с точки зрения объекта". С ее помощью можно графически представить, как одни виды объектов преобразуются в другие или изменяют свое состояние в ходе выполнения рассматриваемого процесса. На OSTN состояния объектов изображаются окружностями с именем объекта внутри, а изменения состояний − соединительными линиями. Состояние объекта описывается фактами и ограничениями, которые должны выполняться, чтобы объект находился в данном состоянии. Требования для перехода объекта в заданное состояние определяются условиями входа. Условия выхода говорят о ситуации, в которой объект выходит из заданного состояния. Эти ограничения описываются в списке свойств. Связи переходов состояний задают возможные способы изменения состояний объектов. Для изображения последовательностей переходов объектов из одного вида в другой и изображения перехода одного и того же объекта из одного состояния в другое в диаграммах OSTN используются связи переходов (Transition Links), которые бывают слабыми (Weak Transition Link) и сильными (Strong Transition Link). Слабые связи переходов изображаются сплошными одинарными стрелками (рисунок 3.14) и показывают, что объекту вида В предшествует объект вида А или что состоянию В некоторого объекта предшествует его состояние А. Рисунок 3.14 - Пример слабой связи переходов 71 Сильные связи переходов изображаются двойными однонаправленными стрелками (рис. 1.15) и подчеркивают, что объекту вида В должен предшествовать объект вида А или что состояние В объекта достижимо только из состояния А. Рисунок 3.15 - Пример сильной связи переходов В диаграммах OSTN используются те же виды ссылок, что и в диаграммах PFDD. Исключение составляет лишь ссылка типа GOTO, которая используется только в диаграммах потоковых процессов PFDD. Ссылки могут относиться как к символу объекта, так и к связи перехода. Соответственно, они интерпретируются как действия, которые необходимо осуществлять для поддержания объекта в данном виде или состоянии, или как действия, которые необходимы для преобразования вида или состояния объекта. Так как процессы поддержания объекта в определенном состоянии и его преобразования могут быть сложными, то допускается использование нескольких ссылок к любому элементу OSTN диаграммы. На диаграммах OSTN могут использоваться перекрестки. Перекресток изображается кружком, внутри которого содержится условное обозначение логической функции, реализуемой перекрестком В качестве логических функций могут использоваться И (&), ИЛИ (O) и ИСКЛЮЧАЮЩЕЕ ИЛИ (X). Как и на диаграммах PFDD, узлы перехода могут означать слияние и разветвление. Но на диаграммах OSTN перекрестки не делятся на асинхронные и синхронные. На рисунке 3.16 показан пример использования узла разветвления с логической функцией ИЛИ. Рисунок 3.16 - Пример перекрестка с логической функцией ИЛИ Диаграмма рис. 1.16 означает, что под действиями UOB с именем P объект из состояния А может перейти в одно или сразу несколько состояний из множества возможных: B1, В2, …, Вn. Если бы в качестве логической функции использовалась функция ИСКЛЮЧАЮЩЕЕ ИЛИ, то это говорило бы, что возможен переход только в одно из возможных состояний B1, В2, …, Вn. Использование же функции И в перекрестке отображало бы переход объекта из состояния А сразу во все состояния B1, В2, …, Вn. На рисунке 3.17 представлено отображение процесса окраски с точки зрения OSTN диаграммы. 72 Рисунок 3.17 - Пример OSTN диаграммы BPwin имеет возможность преобразования диаграмм IDEF3 в имитационную модель популярной системы моделирования Arena.. Контрольные вопросы 1. Дайте определение IDEF0-модели. 2. Что называется декомпозицией в методологии IDEF0? 3. Дайте определение IDEF3-модели. 4. Что отражает DFD-диаграмма? 5. Назовите различия между контекстными диаграммами при IDEF0- и DFDмоделировании? 73 4 Проектирование программного обеспечения при объектном подходе Задачи проектирования включают в себя две составляющие: логическое и физическое проектирование программных продуктов. Логическое проектирование заключается в разработке классов для реализации их экземпляров — объектов. Для этого требуется подробное описание полей и методов классов, а также связей между ними. Для этого используются статические диаграммы классов и объектов, динамические — последовательностей состояний и кооперации. Физическое проектирование предполагает построение программных компонентов из ранее определенных классов и объектов и размещение их на конкретных вычислительных устройствах. Разрабатываемые на этом этапе диаграммы — компонентов и развертывания. 4.1 Разработка структуры программного обеспечения при объектном подходе. Основы унифицированного языка моделирования UML На этапе проектирования уточняются поля и методы классов, а также отношения между классами. Все это находит отражение на диаграмме классов. Для уточнения содержания некоторых классов на диаграмме используют следующие обозначения: управляющий класс (control class) отвечает за координацию действий других классов и контролирует последовательность выполнения действий варианта использования для данного ПО. На каждой диаграмме классов должен быть хотя бы один управляющий класс (рисунок 4.1, а). класс-сущность (entity class) — пассивный класс, информация о котором должна храниться постоянно. Как правило, этот класс соответствует отдельной таблице базы данных. В этом случае его атрибуты являются полями таблицы, а операции — присоединенными или хранимыми процедура ми рисунок 4.1, 6); граничный класс (boundary class) располагается на границе системы с внешней средой. К этому типу относят как классы, реализующие пользовательские интерфейсы, так и классы, обеспечивающие интерфейс с аппаратными средствами или программными системами (рисунок 4.1, в). Рисунок 4.1 – Графическое изображение классов моделирования программного обеспечения Отношения между классами Кроме внутреннего устройства или структуры классов, на диаграмме классов необходимо отобразить различные отношения между ними. Основными отношениями или связями в языке UML являются: отношение зависимости (dependency relationship); отношение ассоциации (association relationship): отношение обобщения (generalization relationship); 74 отношение реализации (realization relationship). Все эти отношения обозначаются по-своему на диаграмме и отражают различные типы взаимосвязей между классами и их объектами. Отношение зависимости Отношение зависимости используется в ситуации, когда не которое изменение одного элемента модели может потребовать изменения другого зависимого от него элемента модели. Отношение зависимости графически изображается пунктир ной линией между соответствующими элементами со стрелкой на одном из ее концов («>» или ««-»). На диаграмме классов данное отношение связывает отдельные классы между собой, при этом стрелка направлена от класса-клиента зависимости к независимому классу или классуисточнику (рисунок 4.2). На дан ном рисунке изображены два класса: Класс А и Класс Б, при этом Класс Б является источником некоторой зависимости, а Класс_А — клиентом этой зависимости. Рисунок 4.2 – Графическое изображение отношения зависимости на диаграмме классов Отношение ассоциации Отношение ассоциации обозначается сплошной линией с дополнительными специальными символами, которые характеризуют отдельные свойства конкретной ассоциации. Это могут быть имя ассоциации, а также имена и кратность классов-ролей ассоциации. Имя ассоциации является необязательным, но если оно задано, то записывается с прописной (заглавной) буквы рядом с линией соответствующей ассоциации. Ассоциация, связывающая два класса (или класс с самим со бой), называется бинарной. Для бинарной ассоциации на диаграмме может быть указан порядок следования классов с использованием треугольника в форме стрелки рядом с именем данной ассоциации. Направление этой стрелки указывает на по рядок классов, один из которых является первым (со стороны основания треугольника), а другой – вторым (со стороны вер шины треугольника). Отсутствие данной стрелки рядом с именем ассоциации означает, что порядок следования классов в рассматриваемом отношении не определен. На рисунке 4.3 показано отношение бинарной ассоциации между классом «Группа» и классом «Студент». Они связаны между собой бинарной ассоциацией «Учеба», имя которой указано на рисунке над линией ассоциации. Порядок следования классов в данном отношении таков: первым является класс «Студент», а вторым – класс «Группа». Рисунок 4.3 – Графическое изображение отношения бинарной ассоциации между классами Можно, хотя это редко бывает необходимо, создавать ассоциации, связывающие сразу несколько классов; они называются N-арными. N-арная ассоциация графически обозначается ромбом, от которого к символам классов данной ассоциации ведут линии. В этом случае ромб 75 соединяется с символами соответствующих классов сплошными линиями. Имя N-арной ассоциации записывается рядом с ромбом соответствующей ассоциации. Рисунок 4.4 – Графическое изображение тернарной ассоциации Пример тернарной ассоциации показан на рисунке 4.4. Здесь изображено отношение между тремя классами: «Футбольная команда», «Год» и «Игра», которое может представлять информацию об играх футбольных команд в национальном чемпионате в течение нескольких последних лет. Наиболее важные свойства ассоциации указываются на диаграмме рядом с этими элементами ассоциации и должны перемещаться вместе с ними. К таким свойствам относятся: имя роли отдельного класса, входящего в ассоциацию, представляет собой строку текста рядом с концом ассоциации для соответствующего класса. Имя роли не является обязательным элементом обозначений и может отсутствовать на диаграмме; кратность отдельных классов, являющихся концами ассоциации. Интервал кратности записывается рядом с концом ассоциации и для N-арной ассоциации означает потенциальное число отдельных экземпляров или значений кортежей этой ассоциации, которые могут иметь место, когда остальные N- 1 экземпляров или значений классов фиксированы. В рассмотренном ранее примере (рисунок 4.2) кратность «l» для класса «Группа» означает, что каждый студент может учиться только в одной группе. Кратность «1..*» для класса «Студент» означает, что в каждой группе могут учиться несколько студентов, общее число которых заранее неизвестно и ничем не ограничено, но всегда больше нуля. На диаграмме классов может присутствовать так называемая исключающая ассоциация (Xorassociation). Она означает, что из нескольких потенциально возможных вариантов данной ассоциации в каждый момент времени может использоваться только один ее экземпляр. Исключающая ассоциация изображается пунктирной линией, соединяющей две ассоциации и более, рядом с которой записывается строка-ограничение {хог}. Рисунок 4.5 – Графическое изображение исключающей ассоциации между тремя классами Например, счет в банке может быть открыт для клиента, в качестве которого может выступать физическое лицо или компания, что изображается с помощью исключающей ассоциации (рисунок 4.5). Отношение агрегации Отношение агрегации имеет место между несколькими классами в том случае, если один из классов представляет собой не которую сущность, включающую в себя в качестве составных частей другие сущности. 76 Данное отношение применяется для представления системных взаимосвязей типа«часть— целое». Раскрывая внутреннюю структуру системы, отношение агрегации показывает, из каких компонентов состоит система и как они связаны между собой. Это отношение по своей сути описывает декомпозицию или раз биение сложной системы на более простые составные части, которые также могут быть подвергнуты декомпозиции, если в этом возникнет необходимость в последующем. При этом части системы никак не обязаны наследовать ее свойства и поведение, поскольку являются вполне самостоятельными сущностями. Более того, части целого обладают своими собственными атрибута ми и операциями, которые могут существенно отличаться от атрибутов и операций целого. Агрегация является частным случаем ассоциации и изображается в виде пустой ассоциации с незакрашенным ромбом со стороны «целого» (рисунок 4.6). Рисунок 4.6 – Графическое изображение отношения агрегации в языке UML Примером отношения агрегации может служить деление персонального компьютера на составные части: системный блок, монитор, клавиатуру и мышь (рисунок 4.7). Рисунок 4.7 – Диаграмма классов для иллюстрации отношения агрегации на примере структуры персонального компьютера Отношение композиции Отношение композиции является частным случаем отношения агрегации. Это отношение служит для описания специальной формы отношения «часть–целое», при которой составляющие части в некотором смысле находятся внутри целого. Причем части не могут выступать в отрыве от целого, т. е. с уничтожением целого уничтожаются и все его составные части. Графически отношение композиции изображается сплошной линией, один из концов которой представляет собой закрашенный внутри ромб. Этот ромб указывает на тот из классов, который представляет собой класс-композицию или «целое» (рисунок 4.8). Рисунок 4.8 – Графическое представление отношения композиции в языке UML Пример отношения композиции – окно интерфейса про граммы, которое может состоять из строки заголовка, кнопок управления размером, полос прокрутки, главного меню, рабочей области и строки состояния. В данном случае наглядно представлено отношение композиции. В качестве дополнительных обозначений для отношений композиции и агрегации могут использоваться дополнительные обозначения, применяемые для отношения ассоциации. А 77 имен но, указание кратности класса ассоциации и имени данной ассоциации, которые не являются обязательными. Диаграмма классов для класса «Окно_программы», описанного выше, может иметь следующий вид (рисунок 4.9). Рисунок 4.9 – Диаграмма классов для иллюстрации отношения композиции на примере класса окна программы Отношение обобщения Отношение обобщения является отношением между более общим элементом (родителем или предком) и более частным или специальным элементом (дочерним или потомком). Применительно к диаграмме классов данное отношение описывает иерархическое строение классов и наследование их свойств и поведения. При этом предполагается, что класс-потомок обладает все ми свойствами и поведением класса-предка, а также имеет свои собственные свойства и повеление, которые отсутствуют у класса-предка. Графически отношение обобщения изображается б виде линии с большой незакрашенной стрелкой, направленной на родителя (рисунок 4.10). Рисунок 4.10 – Графическое изображение отношения обобщения в языке UML Пример отношения обобщения показан на рисунке 4.10. Здесь абстрактный класс «Геометрическая фигура» выступает в качестве суперкласса (класса-предка) для подклассов (классов-потомков), соответствующих конкретным геометрическим фигурам «Прямо угольник», «Окружность», «Эллипс» и др. С целью упрощения обозначений на диаграмме классов совокупность линий, обозначающих одно и то же отношение обобщения, может быть объединена в одну линию. В этом случае данные отдельные линии изображаются сходящимися к единственной стрелке, имеющей с ними общую точку пересечения (рисунок 4.11). Рисунок 4.11 – Пример графического изображения обобщения классов 78 Многоточие вместо прямоугольника на диаграмме означает возможность наличия других классов-потомков, не включенных в обозначения представленных на диаграмме классов. Для того чтобы проиллюстрировать описанные выше типы отношений, рассмотрим следующие пример: Разработать диаграмму классов для некоей компании — класс «Компаниям», которая состоит из нескольких отделов — класс «Отдел», каждый из которых располагается в своем офисе — класс «Офис», имеет штаб-квартиру класс «Штаб-квартира» и содержит штат сотрудников — класс «Person», сведения о которых содержатся в системе кадрового учета. Каждый из вышеприведенных классов обладает своими атрибутами и операциями и связан с другими классами определенным типом отношений. Полученная диаграмма приведена на рисунке 4.12. Рисунок 4.12 – Диаграммы классов Кроме классов на диаграмме могут изображаться интерфейсы. Интерфейсы Интерфейс (interface) — именованное множество операций, характеризующих поведение отдельного элемента модели извне без указания их внутренней структуры. В языке UML интерфейс является специальным случаем класса, у которого имеются операции, но отсутствуют атрибуты. Для обозначений интерфейса на диаграмме классов используется специальный графический символ — окружность, рядом с которой указывается имя интерфейса, или стандартный способ — прямоугольник класса с обозначением «Interface» (рисунок 4.13). 79 Рисунок 4.13 – Обозначения интерфейсов Объекты На этапе проектирования, кроме диаграмм классов, большое значение имеют диаграммы объектов, которые показывают взаимодействие между экземплярами определенных классов в некоторый момент времени. Рисунок 4.14. Обозначения объектов Объект (object) — это отдельный экземпляр класса, который создается на этапе выполнении программы. Он имеет свое собственное имя и конкретные значения атрибутов. Имя объекта представляет собой строку текста «имя объекта» «имя класса», разделенную двоеточием. Для графического изображения объектов используется такой же символ прямоугольника, как и для классов, но имя объекта в отличие от имени класса выделяется подчеркиванием. Пример обозначения объектов приведен на рисунок 4.14. Рисунок 4.15. Пример диаграммы объектов Пример диаграммы объектов компании, состоящей из не скольких отделов – объекты d1, d2, d3 класса «Department», приведен на рисунке 4.15. 80 Диаграммы кооперации Диаграмма кооперации является альтернативным диаграмме последовательностей способом представления взаимодействия объектов. Она показывает потоки данных между объектами классов, что позволяет уточнить отношения между ними. На диаграмме изображаются участвующие во взаимодействии объекты (в виде прямоугольников, содержащих имя объекта, имя его класса и значения атрибутов, если они имеются), а также указываются ассоциации между этими объектами, если необходимо, указывают имя ассоциации и роли объектов и данной ассоциации. Дополнительно могут быть изображены динамические связи – потоки сообщений. Они представляются также в виде соединительных линий между объектами, над которыми располагается стрелка с указанием направления, имени сообщения и порядкового номера в общей последовательности инициализации сообщений. Номера служат для синхронизации сообщений, так как на диаграмме кооперации прямо не указывается время. Пример Разработать диаграмму коопераций, иллюстрирующую взаимоотношения компании с составляющими ее отделами и сотрудниками. Компания организует и расформировывает отделы, принимает и увольняет сотрудников, выдает задание отделам. Сотрудники выполняют работу и сдают отчеты начальникам отделов. Решение приведено на рисунке 4.16. Рисунок 4.16 – Пример диаграммы кооперации Заметим, что на приведенной диаграмме объекты классов «Отдел» и «Сотрудник» реализованы мультиобъектами. Диаграммы компонентов и развертывания выполняются на этапе физического проектирования программных систем для Того, чтобы привязать их к некоторому аппаратному обеспечению. 4.2 Экстремальное программирование Экстремальное программирование (Extreme Programming – XP) – это упрощенная методология организации разработки программ для небольших и средних по размеру команд разработчиков, занимающихся созданием программного продукта в условиях неясных или быстро меняющихся требований. 81 Цели XP Основными целями XP являются повышение доверия заказчика к программному продукту путем предоставления реальных доказательств успешности развития процесса разработки и резкое сокращение сроков разработки продукта. При этом XP сосредоточено на минимизации ошибок на ранних стадиях разработки. Это позволяет добиться максимальной скорости выпуска готового продукта и даёт возможность говорить о прогнозируемости работы. Практически все приемы XP направлены на повышение качества программного продукта. Принципы XP Основными принципами являются: Итеративность. Разработка ведется короткими итерациями при наличии активной взаимосвязи с заказчиком. Итерации как таковые предлагается делать короткими, рекомендуемая длительность – 2-3 недели и не более 1 месяца. За одну итерацию группа программистов обязана реализовать несколько свойств системы, каждое из которых описывается в пользовательской истории. Пользовательские истории (ПИ) в данном случае являются начальной информацией, на основании которой создается модуль. Они отличаются от вариантов использования (ВИ). Описание ПИ короткое – 1-2 абзаца, тогда как ВИ обычно описываются достаточно подробно, с основным и альтернативными потоками, и дополняются моделью. ПИ пишутся самими пользователями, которые в XP являются частью команды, в отличие от ВИ, которые описывает системный аналитик. Отсутствие формализации описания входных данных проекта в XP стремятся компенсировать за счет активного включения в процесс разработки заказчика как полноправного члена команды. Простота решений. Принимается первое простейшее рабочее решение. Экстремальность метода связана с высокой степенью риска решения, обусловленного поверхностностью анализа и жестким временным графиком. Реализуется минимальный набор главных функций системы на первой и каждой последующей итерации; функциональность расширяется на каждой итерации. Интенсивная разработка малыми группами (не больше 10 человек) и парное программирование (когда два программиста вместе создают код на одном общем рабочем месте), активное общение в группе и между группами. Все это нацелено на как можно более раннее обнаружение проблем (как ошибок, так и срыва сроков). Парное программирование направлено на решение задачи стабилизации проекта. При применении XP методологии высок риск потери кода по причине ухода программиста, не выдержавшего интенсивного графика работы. В этом случае второй программист из пары играет роль «наследника» кода. Немаловажно и то, как именно распределены группы в рабочем пространстве – в XP используется открытое рабочее пространство, которое предполагает быстрый и свободный доступ всех ко всем. Обратная связь с заказчиком, представитель которого фактически вовлечен в процесс разработки. Достаточная степень смелости и желание идти на риск. 82 Приемы XP (практики) Обычно XP характеризуют набором из 12 правил (практик), которые необходимо выполнять для достижения хорошего результата. Ни одна из практик не является принципиально новой, но в XP они собраны вместе. 1. Планирование процесса. Вся команда разработчиков собирается вместе, принимается коллективное решение о том, какие свойства системы будут реализованы в ближайшей итерации. Трудоемкость реализации каждого свойства определяется самими программистами. 2. Тесное взаимодействие с заказчиком. Представитель заказчика должен быть членом XP-команды. Он пишет ПИ, выбирает истории, которые будут реализованы в конкретной итерации, и отвечает на вопросы, касающиеся бизнеса. Представитель заказчика должен быть экспертом в автоматизируемой предметной области. Необходимо наличие постоянное обратной связи с представителем заказчика. 3. Общесистемные правила именования. Хорошие системные правила именования предполагают простоту именования классов и переменных. Команда разработчиков должна иметь единые правила именования. 4. Простая архитектура. Любое свойство системы должно быть реализовано как можно проще. Программисты в XP-команде работают под девизом: «Ничего лишнего!». Принимается первое простейшее работающее решение, реализуется необходимый уровень функциональности на данный момент. Тем самым экономится время программиста. 5. Рефакторинг. Это оптимизация существующего кода с целью его упрощения, Такая работа должна вестись постоянно. Сохраняя код прозрачным и определяя его элементы всего один раз, программисты сокращают число ошибок, которые впоследствии придется устранять. При реализации каждого нового свойства системы программист должен подумать над тем, можно ли упростить существующий код и как это поможет реализовать новое свойство. Кроме того, нельзя совмещать рефакторинг с дизайном: если создается новый код, рефакторинг следует отложить. 6. Парное программирование. Все программисты должны работать в парах: один пишет код, другой смотрит. Таким образом, необходимо размещать группу программистов в одном месте. XP наиболее успешно работает в нераспределенных коллективах программистов и пользователей. 7. 40-часовая рабочая неделя. Программист не должен работать более 8 часов в день. Необходимость сверхурочной работы – это четкий индикатор проблемы на данном конкретном направлении разработки. Поиск причин сверхурочной работы и их скорейшее устранение – одно из основных правил. 8. Коллективное владение кодом. Каждый программист в коллективе должен иметь доступ к коду любой части системы и право вносить изменения в любой код. Обязательное правило: если программист внес изменения и система 83 после этого работает некорректно, то именно этот программист должен исправить ошибки. 9. Единые стандарты кодирования. Стандарты кодирования нужны для обеспечения других практик: коллективного владения кодом, парного программирования и рефакторинга. Без единого стандарта выполнять эти практики как минимум сложнее, а в реальности вообще невозможно: группа будет работать в режиме постоянной нехватки времени. Команда работает над проектом продолжительное время. Люди приходят и уходят. Никто не кодирует в одиночку и код принадлежит всем. Всегда будут моменты, когда необходимо будет понять и скорректировать чужой код. Разработчики будут удалять дублирующий код, анализировать и улучшать чужие классы и т. п. Со временем нельзя будет сказать, кто автор конкретного класса. Следовательно, все должны подчиняться общим стандартам кодирования – форматирование кода, именование классов, переменных, констант, стиль комментариев. Вышесказанное означает, что все члены команды должны договориться об общих стандартах кодирования. Неважно каких, но все обязаны им подчиняются. 10. Небольшие релизы. Минимальная итерация – один день, максимальная – месяц; чем чаще осуществляются релизы, тем больше недостатков системы будет выявлено. Первые релизы помогают выявить недостатки на самых ранних стадиях, далее функциональность системы расширяется на основании ПИ. Поскольку пользователь включается в процесс разработки начиная с первого релиза, то он оценивает систему и выдает пользовательскую историю и замечания. На основании этого определяется следующая итерация, то есть, каким будет новый релиз. В XP все направлено на обеспечение непрерывной обратной связи с пользователями. 11. Непрерывная интеграция. Интеграция новых частей системы должна происходить как можно чаще, как минимум раз в несколько часов. Основное правило интеграции следующее: интеграцию можно производить, если все тесты проходят успешно. Если тесты не проходят, то программист должен либо внести исправления и тогда интегрировать составные части системы, либо вообще не интегрировать их. Правило это – жесткое и однозначное. Если в созданной части системы имеется хотя бы одна ошибка, то интеграцию производить нельзя. Частая интеграция позволяет быстрее получить готовую систему, вместо того чтобы тратить на сборку неделю. 12. Тестирование. В отличие от большинства остальных методологий тестирование в XP – одно из важнейших составляющих. Экстремальный подход предполагает, что тесты пишутся до написания кода. Каждый модуль обязан иметь unit test – тест данного модуля. Таким образом, в XP осуществляется регрессионное тестирование, «неухудшение качества» при добавлении функциональности. Большинство ошибок исправляются на стадии кодирования. Тесты пишут сами программисты, любой из них имеет право написать тест для любого модуля. Еще один важный принцип: тест определяет код, а не наоборот (testdriven development), то есть кусок кода кладется в хранилище тогда и только тогда, когда все тесты прошли успешно, в противном случае данное изменение кода отвергается. 84 Процесс XP является неформальным, но требует высокого уровня самодисциплины. Если это правило не выполняется, то XP мгновенно превращается в хаотичный и неконтролируемый процесс. XP не требует от программистов написания множества отчетов и построения массы моделей. В XP каждый программист считается квалифицированным работником, который профессионально и с большой ответственностью относится к своим обязанностям. Если в команде этого нет, то внедрять XP абсолютно бессмысленно – лучше для начала заняться перестройкой команды. Риск разработки снижается только в команде, которой XP подходит идеально, во всех остальных случаях XP – это процесс разработки с наиболее высокой степенью риска, поскольку другие методы снижения коммерческих рисков, кроме человеческого фактора, в XP просто отсутствуют. Контрольные вопросы 1. Для чего нужен язык UML? 2. Перечислите основные отношения между классами. 3. Что такое класс-сущность с точки зрения ООП? 4. Охарактеризуйте модель проектируемого ПО при объектном подходе 5. Что такое экстремальное программирование? 85