Модульное программирование

Автор работы: Пользователь скрыл имя, 17 Марта 2013 в 13:01, курсовая работа

Краткое описание

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

Содержание работы

Введение …………………………………….....…………………………...3
1. Теоретические аспекты модульного программирования ………………..….6
1.1 Цель модульного программирования ………………………………...…..6
1.2 Основные характеристики программного модуля ……………………..14
1.3 Проектирование модуля ……………………………………………….........21
1.3.1 Функциональная декомпозиция ……………………………………….....22
1.3.2 Минимизации количества передаваемых параметров ………………….24
1.3.3 Минимизации количества необходимых вызовов …………..…….25
1.4 Методы разработки структуры модульной программы ...………….....….27
1.5 Контроль структуры модульной программы ...…………………..…34
2. Практическая часть. Код программы "Блокиратор рабочего стола" …….35
Заключение ……………………………………………………………….38
Список исползуемых источников …...………………………..………....39

Содержимое работы - 1 файл

терентьев титульник.docx

— 245.00 Кб (Скачать файл)

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

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

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

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

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

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

В табл. 3.1 представлены характеристики различных  видов связности по экспертным оценкам.  

 

 

 

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

 

1.3 Проектирование модуля

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

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

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

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

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

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

1.3.1 Функциональная декомпозиция

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

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

Рис. 2. Пример функциональной декомпозиции

На  рисунке каждое состояние, т.е. круг на ``графе'', представляет функционально  декомпозированную часть приложения. Функция ввода распределяет частичные  параметры задачи на различные функции 2 - 6, после порождения процессов  соответствующих подпрограмм, реализующих  каждый из подалгоритмов приложения. Некоторые данные могут быть переданы нескольким функциям (как в случае с двумя функциями wing) или данные могут предназначаться только для одной функции. После выполнения некоторого количества вычислений, эти функции доставляют непосредственно конечный результат в функции 7, 8 и 9, которые могут порождаться в начале вычислительного процесса и поэтому быть доступными. Диаграмма отражает первичную концепцию декомпозиции приложений по функциям с тем же успехом, что и отношения зависимости по контролю и данным. Параллелизм достигается благодаря двум причинам: параллельному и независимому исполнению модулей (функциями 2 - 6) плюс одновременному и конвейеризированному исполнению модулей в цепи зависимости (функциями 1, 6, 8 и 9).

1.3.2 Минимизации количества передаваемых параметров

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

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

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

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

1.3.3 Минимизации количества необходимых вызовов

Одним из существенных преимуществ модульного программирования является то, что  программа основного уровня очень  часто может быть сконструирована  для чтения как последовательность вызываемых процедур. Этот факт существенно  повышает «понимаемость» программы, поскольку читатель может познакомиться с ее основным потоком и функционированием после прочтения только одной - двух страниц программного кода. Однако  эта особенность может также иметь и недостатки. Одна из многих верхних статистических оценок программирования говорит о том, что 90% времени выполнения типовых программ расходуется в 10 % кода программы. При этом подразумевается, что если эти 10 % содержат большое количество цепочечных вызовов процедур, то суммарное время, затрачиваемое на управление выполнением программы, может стать непреодолимым препятствием на пути использования этого подхода. Прежде чем отказаться от модульности проектируемой программы, надо проверить, что скрывается под зависимостью программы от времени. Во-первых, большинство программ затрачивают большую часть времени выполнения на ожидание ввода информации с клавиатуры. После нажатия клавиши требуемые функции, с точки зрения выполнения длительного процесса, обычно не расходуют время. Различие между 100 микросекунд и 100 миллисекунд для среднего пользователя неразличимо.

Противоположным для некоторых мнением является то, что действующий механизм пары CALL - RET не перекрывает потребляемое время. По сравнению с инструкциями перехода инструкция CALL выполняется  на 30-50% дольше, а RET в среднем длиннее  на 1 цикл. Только когда во внимание принимаются накладные расходы  передачи параметров, сохранения регистров и т.д., называемые служебными расходами,  модульные программы начинают выглядеть медленнее по сравнению с немодульными программами. В дополнение к тому, что модули модульных программ обычно являются более общими, чем их неструктурированные дубликаты, модули модульных программ могут использовать ссылки на память или стек с большей частотой. Дополнительное время, расходуемое на вычисление действительного адреса в теле модуля, может привести к замедлению выполнения конкретного модуля, чем узко закодированная конкретная программа. Преимущества служебных программ и программ общего назначения заключаются в том, что модуль может быть использован виртуально в некотором месте программы. При написании немодульной программы программист может потратить несколько часов, пытаясь открыть: используется ли регистр (переменная), или хуже того, верно ли то, что он должен использоваться. При модульном программировании программист не интересуется тем, какие регистры (переменные) он использует в настоящий момент, пока вызываемый модуль копирует его параметры в стек и сохраняет весь набор регистров на входе. Эти особенности создают возможность сначала использовать приемы модульного программирования для повышения скорости кодирования и затем переработки программы для удаления "узких" мест.

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

1.4 Методы разработки структуры модульной программы

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

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

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

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

Недостатки  метода восходящей разработки заключаются  в  следующем:

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

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

Информация о работе Модульное программирование