Модульное программирование процедуры и функции. Модульное программирование. Классическая проблема программирования

Модульное программирование работает по принципу «разделяй и властвуй». Стоит разобраться.

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

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

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

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

Цели урока:

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

ХОД УРОКА

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

1.1. Устный опрос:

  • Какой вид имеет структура описания процедуры и функции в Turbo Pascal?
  • В чем состоит отличие описания процедуры и функции?
  • Что такое область действия идентификаторов?
  • Какие параметры называются формальными и какие фактическими?
  • Какие способы передачи параметров реализованы в Turbo Pascal?
  • Почему при работе с графикой в Turbo Pascal необходимо предложение uses Graph?
  • Какие процедуры и функции модуля Graph вам известны?

2. Изложение нового материала.

2.1.1. Технология модульного программирования.

Языки высокого уровня появились в 60-е годы. Ресурсы ЭВМ (объем ОЗУ 8 Кбайт, быстродействие 20 тыс. операций в сек.) были недостаточны, поэтому программисты вынуждены были писать программы весьма “хитроумно” с использованием оператора безусловного перехода. Программа получалась запутанной, имела структуру “блюдо спагетти”. Так как область применения ЭВМ расширялась, программное обеспечение усложнялось. Программисты, решающие сложные задачи, столкнулись с проблемой разрастания количества и размера программ до такой степени, что дальнейший процесс разработки становился практически неуправляемым, и никто из разработчиков не мог с уверенностью сказать, что созданный программный продукт всегда выполняет то, что требуется, и что он не выполняет ничего такого, что не требуется. Поэтому возникла необходимость в новой методологии разработки программных проектов. В 1968–1969 гг. состоялись конференции по программированию. На второй из них Эдсгер Дийкстра предложил принципиально новый способ создания прграмм – структурное программирование. Главное – разбиение программного комплекса (при его создании) на программные модули, которые соединяются иерархически.

Цели модульного программирования:

1. Улучшать читабельность программ.
2. Повышать эффективность и надежность программ (легко находить и корректировать ошибки).
3. Уменьшать время и стоимость программной разработки (уменьшается время отладки).

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

  1. Модуль – это независимый блок, код которого физически и логически отделен от кода других модулей.
  2. Размер модуля не больше 100 операторов.
  3. Имеет одну входную и одну выходную точку.
  4. Модули связаны иерархически.
  5. Разбиение должно обеспечивать надежное скрытие информации в модуле.
    Парнас: “Для написания одного модуля должно быть достаточно минимальных знаний о тексте другого”.
  6. Каждый модуль должен начинаться с комментария (его назначение – входные и выходные переменные).
  7. Не использовать метки и оператор GOTO.
  8. Использовать только стандартные управляющие конструкции (условие, выбор, цикл, блок).

2.1.2. Нисходящее и восходящее программирование .

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

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

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

Недостатки нисходящего проектирования:

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

Преимущество нисходящего проектирования – на самом начальном этапе проектирования отлаживается головной модуль (логика программы).

Преимущество восходящего программирования – не нужно писать заглушки.

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

На практике применяются оба метода. Метод нисходящего проектирования чаще всего применяется при разработке нового программного комплекса, а метод восходящего проектирования – при модификации уже существующего комплекса.

2.1.3. Оформление программы в виде модуля.

При подключении стандартных модулей достаточно корректно записать их идентификаторы в предложении uses. При разработке собственных модулей необходимо помнить некоторые особенности:

  • Не допускается одновременное использование модулей с одинаковыми именами.
  • Идентификатор модуля, указанный в заголовке (unit ), должен совпадать с именами файлов, содержащих исходный (.pas ) (.tpu , . tpp , .tpw ) код.
  • Если идентификатор модуля длиннее восьми символов, то он должен совпадать с именами файлов по первым восьми символам.

Общая структура модуля

unit идентификатор модуля;

{Интерфейсный раздел }

interface

в этом разделе описывается взаимодействие данного модуля с другими пользовательскими и стандартными модулями, а также с главной программой. Другими словами – взаимодействие модуля с “внешним миром”.

Список импорта интерфейсного раздела

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

Список экспорта интерфейсного раздела

const
type
var
procedure
function

Раздел реализации

Implementation

в этом разделе указывается реализационная (личная) часть описаний данного модуля, которая недоступна для других модулей и программ. Другими словами – “внутренняя кухня модуля”.

Список импорта раздела реализации

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

Подразделы внутренних для модуля описаний

label
const
type
var
procedure
function

Раздел инициализации

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

2.2. Примеры.

Пример модуля a1

unit a1;
interface
uses graph;
procedure init;
procedure pr1;
implementation
procedure init;
{инициализация графического режима}
procedure pr1;
begin
{команды построения фрагмента изображения}
end;
begin
init;
pr1;
readln;
end.

Головной модуль

program a;
uses a1, a2, a3, a4;
begin
pr1;
pr2;
pr3;
pr4;
readln;
end.

3. Проверка качества усвоения нового материала.

3.1. Устный опрос .

  • Назовите принципы модульного программирования.
  • Когда применяется технология нисходящего программирования? А восходящего?
  • В чем различие между технологией восходящего и технологией нисходящего программирования?
  • Какие существуют особенности при разработке собственных модулей?
  • Из каких разделов состоит модуль?
  • Что описывается в разделе interface?
  • Что описывается в разделе implementation?
  • Что описывается в разделе инициализации?

3.2. Самостоятельная работа учащихся на уроке .

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

Литература:

  1. Марченко А. И., Марченко Л. М. “Программирование в среде Turbo Pascal 7.0”, М.: “Бином Универсал”, 1998.
  2. Информатика. № 2. /Приложение к газете “Первое сентября”, 1996.

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

Концепции модульного программирования. В основе модульного программирования лежат три основных концепции:

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

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

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

· синтаксическая обособленность, т. е. выделение модуля в тексте синтаксическими элементами;

· семантическая независимость, т. е. независимость от места, где программная единица вызвана;

· общность данных, т. е. наличие собственных данных, сохраняющихся при каждом обращении;

· полнота определения, т. е. самостоятельность программной единицы.

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

· стремление к выделению независимой единицы программного знания. В идеальном случае всякая идея (алгоритм) должна быть оформлена в виде модуля;

· потребность организационного расчленения крупных разработок;

· возможность параллельного исполнения модулей (в контексте параллельного программирования).

Определения модуля и его примеры. Приведем несколько дополнительных определений модуля.

· Модуль - это совокупность команд, к которым можно обратиться по имени.

· Модуль - это совокупность операторов программы, имеющая граничные элементы и идентификатор (возможно агрегатный).

Функциональная спецификация модуля должна включать:

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

· описание семантики функций, выполняемых модулем по каждому из его входов.

Разновидности модулей. Существуют три основные разновидности модулей:

1) "Маленькие" (функциональные) модули, реализующие, как правило, одну какую-либо определенную функцию. Основным и простейшим модулем практически во всех языках программирования является процедура или функция.

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

a)задачи в языке программирования Ada;

b)кластер в языке программирования CLU;

c)классы в языках программирования C++ и Java.

3) "Большие” (логические) модули , объединяющие набор "средних" или "маленьких" модулей. Примеры "больших" модулей в языках программирования:

a)модуль в языке программирования Modula-2;

b)пакеты в языках программирования Ada и Java.

Набор характеристик модуля предложен Майерсом [Майерс 1980]. Он состоит из следующих конструктивных характеристик:

1) размера модуля;

В модуле должно быть 7 (+/-2) конструкций (например, операторов для функций или функций для пакета). Это число берется на основе представлений психологов о среднем оперативном буфере памяти человека. Символьные образы в человеческом мозгу объединяются в "чанки" - наборы фактов и связей между ними, запоминаемые и извлекаемые как единое целое. В каждый момент времени человек может обрабатывать не более 7 чанков.

Модуль (функция) не должен превышать 60 строк. В результате его можно поместить на одну страницу распечатки или легко просмотреть на экране монитора.

2) прочности (связности) модуля;

Существует гипотеза о глобальных данных, утверждающая, что глобальные данные вредны и опасны. Идея глобальных данных дискредитирует себя так же, как и идея оператора безусловного перехода goto. Локальность данных дает возможность легко читать и понимать модули, а также легко удалять их из программы.

Связность (прочность) модуля (cohesion) - мера независимости его частей. Чем выше связность модуля - тем лучше, тем больше связей по отношению к оставшейся части программы он упрятывает в себе. Можно выделить типы связности, приведенные ниже.

Функциональная связность. Модуль с функциональной связностью реализует одну какую-либо определенную функцию и не может быть разбит на 2 модуля с теми же типами связностей.

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

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

Обратим внимание на то, что средства для задания информационно прочных модулей отсутствовали в ранних языках программирования (например, FORTRAN и даже в оригинальной версии языка Pascal). И только позже, в языке программирования Ada, появился пакет - средство задания информационно прочного модуля.

3) сцепления модуля с другими модулями;

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

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

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

· Сцепление по простым элементам данных.

· Сцепление по структуре данных. В этом случае оба модуля должны знать о внутренней структуре данных.

4) рутинности (идемпотентность, независимость от предыдущих обращений) модуля.

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

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

· В большинстве случаев делаем модуль рутинным, т. е. независимым от предыдущих обращений.

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

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

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

Заметим, что нужно различать использование слова "модуль", когда имеется в виду синтаксическая конструкция языков программирования (unit в Object Pascal), и когда имеется в виду единица дробления большой программы на отдельные блоки (которые могут быть реализованы и в виде процедур, и в виде функций).

Использование модульного программирования позволяет упростить тестирование программы и обнаружение ошибок. Аппаратно-зависимые подзадачи могут быть строго отделены от других подзадач, что улучшает мобильность создаваемых программ.

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

Термин "модуль" в программировании начал использоваться в связи с внедрением модульных принципов при создании программ. В 70-х годах под модулем понимали какую-либо процедуру или функцию, написанную в соответствии с определенными правилами. Например "Модуль должен быть простым, замкнутым (независимым), обозримым (от 50 до 100 строк), реализующим только одну функцию задачи, имеющим только одну входную и только одну выходную точку". Однако общепризнанных требований не было и модулем очень часто называли любую процедуру размером до 50 строк.

Первым основные свойства программного модуля более-менее четко сформулировал Парнас (Parnas): "Для написания одного модуля должно быть достаточно минимальных знаний о тексте другого". Таким образом! Парнас первым выдвинул концепцию скрытия информации (information! hiding) в программировании.

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

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

Впервые специализированная синтаксическая конструкция модуля была предложена Н.Виртом в 1975 г. и включена в его новый язык Modula. В этом же году была сделана опытная реализация языка Modula. После некоторой переработки этот новый язык был окончательно реализован в 1977 г. и получил название Modula-2. Впоследствии, аналогичные конструкции, с некоторыми отличиями, были включены и в другие языки программирования: Pascal Plus (Уэлш и Бастард, 1979 г.), Ada (1980), Turbo Pascal версии 4.0 и другие.

Изначально предполагалось, что при реализации сложных программных комплексов модуль должен использоваться наравне с процедурами и функциями как конструкция, объединяющая и надежно скрывающая детали реализации определенной подзадачи. Однако в языке Borland (Turbo) Pascal были реализованы не все теоретические возможности модуля. В частности, в этом языке отсутствует поддержка внутренних модулей (аналогичных внутренним процедурам и функциям), недостаточно гибко реализован импорт (предложение uses), который не позволяет импортировать объекты из других модулей выборочно. Это обстоятельство, а также то, что с появлением персональных компьютеров круг программирующих людей резко расширился (а это существенно снизило средний уровень теоретической подготовки программистов), привело к тому, что при разработке приложений на этой, предшествующей Object Pascal, версии языка модули использовались в основном как средство создания проблемных библиотек процедур и функций. И только наиболее квалифицированные программисты использовали всю мощь этой языковой конструкции для структурирования своих проектов. В языке Object Pascal отмеченные ограничения реализации модулей остались, однако благодаря тому, что в среде Delphi каждой форме обязательно соответствует свой модуль и не визуальные алгоритмические действия также, как правило, оформляются в виде отдельных модулей, конструкцию "модуль" стали использовать по ее первоначальному предназначению все программисты, независимо от их квалификации.

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

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

Рассмотрим еще один теоретический вопрос, связанный с использованием модульного программирования. Этот вопрос касается формы модульного проекта.

Придание иерархической структуре модульного проекта хорошей формы позволяет улучшить процесс ее разработки. Число модулей, которые подключаются каким-либо модулем, и число модулей, которые его подключают, оказывают влияние на сложность проекта. Йордан (Yourdon) назвал число модулей, подключаемых из данного модуля, размахом или шириной управления модулями. Наряду с большим размером модуля очень маленькая или очень большая ширина управления является признаком плохой схемы разбивки на модули. В общем случае, ширина управления модуля не должна превышать 10-ти. Это число связано с "магическим" числом 7, которое базируется на положениях психологии, в особенности, на теории "кусков" ("chunking") информации. Кратковременная память человека имеет ограниченные способности сохранения "кусков" информации. Психологические эксперименты показали, способность нашей кратковременной памяти находится в пределах 5-11 "кусков" (в среднем - 7). Она может одновременно оперировать около 7 "кусками" информации. Когда человек превышает этот предел, он более склонен к ошибкам. Реорганизация информации с разбивкой на подходящие части является важным действием для эффективного использования кратковременной памяти человека и для улучшения понимаемого материала. Люди во многих жизненных ситуациях делают такую реорганизацию бессознательно. Однако программист может сам себе помочь, сознательно не допуская ширины управления модулями, которая существенно превышает число 7.

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

Кроме того, эти же принципы следует применять и при проектировании иерархии классов. Например, в иерархии предопределенных классов Object Pascal, только два класса, TObject и Exception, имеют число непосредственных классов-потомков, значительно большее, чем 7. Это можно объяснить глобальной базовой ролью TObject и "перечисляемым" характером класса Exception. Еще у троих классов это число находится в пределах 8-9, а остальные классы имеют менее 7 непосредственных потомков.

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

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

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

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

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

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

Все модули используют мнемонические имена для определяемых ими объектов (констант , переменных , типов и подпрограмм), что облегчает понимание их назначения и запоминание, удовлетворяет требованию наглядности текста программ.

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

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

Модули служат также целям создания проблемно-ориентированного контекста и локализации машинной зависимости.

Концепция модульного программирования

Концепцию модульного программирования можно сформулировать в виде нескольких понятий и положений:

  • Функциональная декомпозиция задачи - разбиение большой задачи на ряд более мелких, функционально самостоятельных подзадач - модулей. Модули связаны между собой только по входным и выходным данным.
  • Модуль - основа концепции модульного программирования. Каждый модуль в функциональной декомпозиции представляет собой "черный ящик " с одним входом и одним выходом. Модульный подход позволяет безболезненно производить модернизацию программы в процессе ее эксплуатации и облегчает ее сопровождение. Дополнительно модульный подход позволяет разрабатывать части программ одного проекта на разных языках программирования, после чего с помощью компоновочных средств объединять их в единый загрузочный модуль.
  • Реализуемые решения должны быть простыми и ясными. Если назначение модуля непонятно, то это говорит о том, что декомпозиция начальной или промежуточной задачи была проведена недостаточно качественно. В этом случае необходимо еще раз проанализировать задачу и, возможно, провести дополнительное разбиение на подзадачи. При наличии сложных мест в проекте их нужно подробнее документировать с помощью продуманной системы комментариев. Этот процесс нужно продолжать до тех пор, пока действительно не удастся добиться ясного понимания назначения всех модулей задачи и их оптимального сочетания.
  • Назначение всех переменных модуля должно быть описано с помощью комментариев по мере их определения.

Литература

  1. М.М. Бежанова, Л.А. Москвина. Практическое программирование. Приемы создания программ на языке Паскаль. М.: Научный Мир, 2000, 270 с.
  2. Истомин Е.П., Новиков В.В., Новикова М.В. Высокоуровневые методы информатики и программирования: Учебник. - СПб. ООО "Адреевский издательский дом", 2006 г. - 228 с.