Материал: [2 курс] Программная инженерия

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Разработка структуры программы и модульное программирование

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

  1. Размер модуля определяется количеством использованных в нем операторов. Модуль не может быть слишком маленьким или слишком большим. Обычно рекомендуются модули до нескольких сотен операторов.

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

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

Не рекомендуется к использованию.

    1. Функционально-прочный модуль – модуль, реализующий одну определенную функцию. При реализации такой функции модуль может использовать другие модули. НАИБОЛЕЕ рекомендуемый для использования.

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

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

    1. Сцепление по содержимому (худший вариант) – это сцепление двух модулей, когда один модуль имеет прямые ссылки на содержимое другого модуля.

    2. Сцепление по общей области (также не рекомендуется) – разные модули используют одну и ту же область памяти (например, глобальные переменные).

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

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

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

Методы разработки структуры программы

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

  1. Метод восходящей разработки

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

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

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

  1. Метод снисходящей разработки

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

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

  1. Конструктивный подход

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

  1. Архитектурный подход

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

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

Контроль структуры программы

Для контроля структуры программы используются 3 метода:

  1. Статический контроль – оценка структуры программы

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

  1. Смежный контроль – имеет 2 модификации

Смежный контроль сверху – контроль со стороны разработчиков архитектуры ПС и внешнего описания

Смежный контроль снизу – контроль со стороны разработчиков модулей

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

Разработка программного модуля

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

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

  2. Выбор алгоритма и структуры данных

  3. Программирование модуля

  4. Шлифовка (оптимизация) текста модуля

  5. Проверка модуля (включая тестирование)

  6. Компиляция модуля

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

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

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

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

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

На последнем шаге предусматривает завершение проверки модуля и подготовка программного продукта.

Структурное программирование

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

  1. Следование – линейная структура, определяющая последовательность действий

  2. Разветвление – предполагает наличие условия (if – else), в зависимости от которого выполняется одна из двух ветвей

  3. Повторение – обычный цикл

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

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

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

Источник: https://studfile.net/preview/15917400/