Модульное программирование
Мо́дульное программи́рование — организация программы как совокупности небольших независимых блоков, называемых модулями, структура и поведение которых подчиняются определённым правилам[1].
Использование модульного программирования позволяет упростить тестирование программы и обнаружение ошибок. Аппаратно-зависимые подзадачи могут быть строго отделены от других подзадач, что улучшает мобильность создаваемых программ.
Модуль — последовательность логически связанных фрагментов, оформленных как отдельная часть программы[2]. Во многих языках оформляется в виде отдельного файла с исходным кодом или поименованной непрерывной её части, что обеспечивает раздельную компиляцию модулей[3]. При построении модуля используется концепция: «один модуль — одна функция», то есть модуль — элемент программы, решающий одну самостоятельную задачу. Некоторые языки предусматривают объединение модулей в пакеты[4].
Модульное программирование обеспечивает упрощение проектирования программного обеспечения и распределения процесса разработки между группами разработчиков. Необходимость разработки больших программных систем привела к появлению модульного программирования, когда весь проект разбивается на составные части, называемые модулями, причём каждый из них имеет свой контролируемый размер, чёткое назначение и детально проработанный интерфейс с внешней средой[5]. Кроме того, модульное программирование упрощает процессы обновления кода и рефакторинга и позволяет заменять один модуль другим.
Роль модулей могут играть структуры данных, библиотеки функций, классы, сервисы и другие программные единицы, реализующие некоторую функциональность и предоставляющие интерфейс к ней. Одним из методов написания модульных программ является объектно-ориентированное программирование, использующее такие свойства, как инкапсуляция, полиморфизм и позднее связывание.
Модульная система модулей
[править | править код]Несмотря на то, что модульное программирование никак не связано с деталями конкретного определенного языка (и даже в случае отсутствия явной поддержки со стороны языка может применяться при достаточной дисциплине со стороны программистов), большинство языков выдвигают на верхний уровень свою собственную систему модулей, словно перенос системы модулей с одного языка на другой был бы невозможен[6].
В 2000 году Ксавье Леруа предложил делать системы модулей модульными, то есть параметризуемыми описанием конкретного ядра языка со своей системой типов[7]. В качестве примера он продемонстрировал обобщённую реализацию языка модулей ML (как наиболее развитой системы модулей из известных на данный момент) и примеры её инстанцирования на традиционный для неё язык ML и на язык Си.
Реализация Леруа сама построена посредством языка модулей ML, а именно в виде функтора, параметризованного данными о ядре языка и описанием его механизма проверки согласования типов. Это значит, что при написании компилятора некоторого языка достаточно описать ядро языка и передать его данному функтору (как библиотечной функции) — в результате получится компилятор расширения известного языка системой модулей ML.
История
[править | править код]История концепции модулей как единиц компиляции восходит к языкам Фортран II и Кобол, то есть, к концу 1950-х годов[8][9]. В 1976 году появилась публикация, в которой была развита концепция модульности — о языке Mesa[англ.], который был разработан в Xerox PARC. В 1977 году подробно ознакомился с этой концепцией учёный Никлаус Вирт, общаясь с разработчиками в Xerox PARC.[10] Эти идеи были использованы Виртом при создании языка Модула-2, публикация о котором вышла в 1977 году[11].
Термин «модуль» в программировании начал использоваться в связи с внедрением модульных принципов при создании программ. В 1970-х годах под модулем понимали какую-либо процедуру или функцию, написанную в соответствии с определёнными правилами. Например: «модуль должен быть простым, замкнутым (независимым), обозримым (от 50 до 100 строк), реализующим только одну функцию задачи, имеющим одну входную и одну выходную точку».
Первым основные свойства программного модуля сформулировал Дэвид Парнас[англ.] в 1972 году: «для написания одного модуля должно быть достаточно минимальных знаний о тексте другого». Таким образом, в соответствии с определением, модулем могла быть любая отдельная процедура (функция) как самого нижнего уровня иерархии (уровня реализации), так и самого верхнего уровня, на котором происходят только вызовы других процедур-модулей[12]. Таким образом, Парнас первым выдвинул концепцию скрытия информации (англ. information hiding) в программировании. Однако существовавшие в языках 1970-х годов только такие синтаксические конструкции, как процедура и функция, не могли обеспечить надёжного скрытия информации, из-за повсеместного применения глобальных переменных.
Решить эту проблему можно было только разработав новую синтаксическую конструкцию, которая не подвержена влиянию глобальных переменных. Такая конструкция была создана и названа модулем. Изначально предполагалось, что при реализации сложных программных комплексов модуль должен использоваться наравне с процедурами и функциями как конструкция, объединяющая и надёжно скрывающая детали реализации определённой подзадачи.
Таким образом, количество модулей в комплексе должно определяться декомпозицией поставленной задачи на независимые подзадачи. В предельном случае модуль может использоваться даже для заключения в него всего лишь одной процедуры, если необходимо, чтобы выполняемое ею локальное действие было гарантировано независимым от влияния других частей программы при любых изменениях.
Впервые специализированная синтаксическая конструкция модуля была предложена Никлаусом Виртом в 1975 году и включена в его новый язык Модула.
Реализация в языках программирования
[править | править код]Языки, формально поддерживающие концепцию модулей: язык ассемблера IBM S/360, Кобол, RPG, ПЛ/1, Ада, D, F[англ.], Фортран, Haskell, Blitz BASIC, OCaml, Паскаль, ML, Модула-2, Оберон, Компонентный Паскаль, Zonnon, Erlang, Perl, Python и Ruby.
Модульное программирование может быть осуществлено, даже когда синтаксис языка программирования не поддерживает явное задание имён модулям.
Программные инструменты могут создавать модули исходного кода, представленные как части групп — компонентов библиотек, которые составляются с программой компоновщиком.
См. также
[править | править код]Примечания
[править | править код]- ↑ https://cyberpedia.su/6x88a4.html Архивная копия от 22 октября 2013 на Wayback Machine
- ↑ Модульное программирование — Студопедия . studopedia.ru. Дата обращения: 21 ноября 2022. Архивировано 21 ноября 2022 года.
- ↑ Модульность программного кода — КиберПедия . cyberpedia.su. Дата обращения: 21 ноября 2022. Архивировано 21 ноября 2022 года.
- ↑ Разработка программного обеспечения . poisk-ru.ru. Дата обращения: 21 ноября 2022. Архивировано 21 ноября 2022 года.
- ↑ End Sub. При выполнении первой подпрограммы (proc1) в этом примере происходит вызов процедуры (AcB) . lektsii.org. Дата обращения: 21 ноября 2022. Архивировано 21 ноября 2022 года.
- ↑ Leroy, 2000.
- ↑ Структурное и модульное программирование — КиберПедия . cyberpedia.su. Дата обращения: 21 ноября 2022. Архивировано 21 ноября 2022 года.
- ↑ A brief history of FORTRAN
- ↑ COBOL Subprograms . Дата обращения: 23 октября 2009. Архивировано 5 мая 2009 года.
- ↑ Никлаус Вирт. Краткая история Modula и Lilith Архивная копия от 20 января 2007 на Wayback Machine, перевод с англ. с комментариями в тексте Р. Богатырева
- ↑ The History of Modula-2 and Oberon . Дата обращения: 22 октября 2009. Архивировано 1 июня 2012 года.
- ↑ Parnas D. L. On the criteria to be used in decomposing systems into modules (англ.) // Communications of the ACM. — 1972. — Vol. 15, no. 12. — doi:10.1145/361598.361623.
Литература
[править | править код]- Xavier Leroy. A Modular Module System // vol.10, issue 3. — Journal of Functional Programming, 2000. — С. 269–303.