Модульность
Модуль — фрагмент программного текста, являющийся строительным блоком для физической структуры системы. Как правило, модуль состоит из интерфейсной части и части-реализации.
Модульность — свойство системы, которая может подвергаться декомпозиции на ряд внутренне связанных и слабо зависящих друг от друга модулей.
По определению Г. Майерса, модульность — свойство ПО, обеспечивающее интеллектуальную возможность создания сколь угодно сложной программы [52]. Проиллюстрируем эту точку зрения.
Пусть С(х) — функция сложности решения проблемы х, Т(х) — функция затрат времени на решение проблемы х. Для двух проблем р1 и р2 из соотношения С(р1) > С(р2) следует, что
T(pl)>T(p2). (4.1)
Этот вывод интуитивно ясен: решение сложной проблемы требует большего времени.
Далее. Из практики решения проблем человеком следует:
С(р1+ р2)>С(р1) + С(р2).
Отсюда с учетом соотношения (4.1) запишем:
T(pl+p2)>T(pl) + T(p2). (4.2)
Соотношение (4.2) — это обоснование модульности. Оно приводит к заключению «разделяй и властвуй» — сложную проблему легче решить, разделив ее на управляемые части. Результат, выраженный неравенством (4.2), имеет важное значение для модульности и ПО. Фактически, это аргумент в пользу модульности.
Однако здесь отражена лишь часть реальности, ведь здесь не учитываются затраты на межмодульный интерфейс. Как показано на рис. 4.11, с увеличением количества модулей (и уменьшением их размера) эти затраты также растут.
Рис. 4.11. Затраты на модульность
Таким образом, существует оптимальное количество модулей Opt, которое приводит к минимальной стоимости разработки. Увы, у нас нет необходимого опыта для гарантированного предсказания Opt. Впрочем, разработчики знают, что оптимальный модуль должен удовлетворять двум критериям:
q снаружи он проще, чем внутри;
q его проще использовать, чем построить.
В языках C++, Object Pascal, Ada 95 абстракции классов и объектов формируют логическую структуру системы. При производстве физической структуры эти абстракции помещаются в модули. В больших системах, где классов сотни, модули помогают управлять сложностью. Модули служат физическими контейнерами, в которых объявляются классы и объекты логической разработки.
Модульность определяет способность системы подвергаться декомпозиции на ряд сильно связанных и слабо сцепленных модулей.
Общая цель декомпозиции на модули: уменьшение сроков разработки и стоимости ПС за счет выделения модулей, которые проектируются и изменяются независимо. Каждая модульная структура должна быть достаточно простой, чтобы быть полностью понятой. Изменение реализации модулей должно проводиться без знания реализации других модулей и без влияния на их поведение.
Определение классов и объектов выполняется в ходе логической разработки, а определение модулей — в ходе физической разработки системы. Эти действия сильно взаимосвязаны, осуществляются итеративно.
В Ada 95 мощным средством обеспечения модульности является пакет.
Пример: пусть имеется несколько программ управления полетом летательного аппарата (ЛА) — программа угловой стабилизации ЛА и программа управления движением центра масс ЛА. Нужно создать модуль, чье назначение — собрать все эти программы. Возможны два способа.
1. Присоединение с помощью указателей контекста:
with Класс_УгловСтабил, Класс_ДвиженЦентраМасс;
use Класс_УгловСтабил, Класс_ДвиженЦентраМасс;
Package Класс_УпрПолетом is
…
2. Встраивание программ управления непосредственно в объединенный модуль:
Package Класс_УпрПолетом is
type УгловСтабил is tagged private;
type ДвиженЦентраМасс is tagged private;
-------------------------