Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Модульность



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

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

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

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

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

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

Итак, интерфейс стека будет помещен в файл stack.h.

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

void push(int el);

int pop ();

Код пользователя будет находиться, например, в файле user.c:

#include "stack.h" // включить интерфейс

main (void)

{

push (1);

if (pop ()!= 1)...; //???

...

}

Файл, содержащий реализацию модуля Stack, может называться, например, stack.c:

#include "stack.h" // включить интерфейс

int stack [100]; //реализация

int top;

void push (int el){...}

int pop (){...}

Тексты user.c и stack.c совместно используют информацию об интерфейсе, содержащуюся в stack.h. Во всем другом эти два файла независимы и могут быть раздельно откомпилированы. Графи­ческое изображение упомянутых фрагментов программы представлено на рис. 2.1.

Рис. 2.1 Структура модулей программы, использующей стек

Если стек представлен в виде объекта типа Stack, введенного с использованием понятия класс, то информация о данных, агрегированных в этот новый тип, (а не только о предоставляемом им интерфейсе) также должна быть доступна при компиляции пользовательского кода на языке С++.

Предположим, что компилятор встречает объявление объекта

Stack My_stack;

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

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

В результате файл stack.h должен содержать описание структуры или класса Stack, приведенное в п. 2.2.

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

В объектно-ориентиро­ванном программировании по модулям необходимо распре­делить классы и объекты.

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

Рассмотрим приемы и правила, которые позволяют составлять модули наиболее эффективным обра­зом:

– конечной целью разбиения программы на модули является снижение затрат на программирование за счет независимой раз­работки и тестирования;

– структура модуля должна быть достаточно простой для восприятия;

– реализация каждого модуля не должна зависеть от реализации других модулей;

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

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

– особенности системы, подвер­женные изменениям, следует скрывать в отдельных модулях;

– в качестве межмо­дульных можно использовать только те элементы, вероятность изменения кото­рых мала;

– все структуры данных должны быть обособлены в модуле; доступ к ним будет возможен для всех процедур этого модуля и закрыт для всех других;

– доступ к данным из модуля должен осуществляться только через процедуры данного мо­дуля.

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

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

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

В результате всего сказанного сформулируем следующее определение модульности:

Модульность – это свойство системы, которая была разложена на внутренне связные, но слабо связанные между собой модули.

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

Подсисте­ма – это агрегат, содержащий другие модули и другие подсистемы. Каждый модуль в системе должен располагаться в одной подсистеме или находиться на самом верхнем уровне.

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





Дата публикования: 2015-04-06; Прочитано: 347 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.007 с)...