Модуля или модули как правильно
Значение слова «модуль»
1. Физ., тех. Название некоторых (особенно важных в какой-л. области) коэффициентов или величин. Модуль сжатия. Модуль упругости.
2. Архит. Исходная единица измерения, устанавливаемая для данного архитектурного сооружения, служащая мерилом для придания соразмерности отдельным частям здания.
3. Тех. Часть прибора или конструкции, собранная из типовых деталей и имеющая многоцелевое применение.
[От лат. modulus — мера]
Источник (печатная версия): Словарь русского языка: В 4-х т. / РАН, Ин-т лингвистич. исследований; Под ред. А. П. Евгеньевой. — 4-е изд., стер. — М.: Рус. яз.; Полиграфресурсы, 1999; (электронная версия): Фундаментальная электронная библиотека
Модуль — функционально завершённый узел радиоэлектронной аппаратуры, оформленный конструктивно как самостоятельный продукт. См. также: унификация.
Модуль (космонавтика) — автономно управляемая часть космического корабля (например, модуль МКС).
Модуль — предварительно заданная величина, размер, кратным которому принимаются остальные размеры при разработке или при оценке проекта здания.
Модуль — шаг сетки, основа композиции полос и разворотов в модульной системе вёрстки.
Модуль — произведение длины между перпендикулярами, ширины и высоты борта судна в судостроении.
Модуль (реклама) — размеры графики для печатной рекламы.
Модуль зубчатого колеса — основной параметр зубчатой передачи.
НТЦ «Модуль» — компания, учреждённая в 1990 году предприятиями НПО «Вымпел» и НИИ Радиоприборостроения.
Модуль (программирование) — функционально законченный фрагмент программы, оформленный в виде отдельного файла с исходным кодом или поименованной непрерывной её части.
Исполнимый модуль — файл, содержащий программу в виде, в котором она может быть исполнена компьютером.
Объектный модуль — файл с промежуточным представлением отдельного модуля программы, полученный в результате обработки исходного кода компилятором.
Модуль ядра — объект, содержащий код, который расширяет функциональность запущенного или т. н. базового ядра ОС.
Модули римановой поверхности
Модуль над кольцом, в частности Нётеров модуль.
МОДУЛЬ
Смотреть что такое «МОДУЛЬ» в других словарях:
Модуль — (от лат. modulus «маленькая мера»): В Викисловаре есть статья «модуль» Мо … Википедия
МОДУЛЬ — (в математике) мера для сравнения однородных величин и для выражения одной из них помощью другой; м. выражается числом. Словарь иностранных слов, вошедших в состав русского языка. Павленков Ф., 1907. МОДУЛЬ (лат.). 1) число, которым множатся… … Словарь иностранных слов русского языка
модуль — я, м. module <лат. modulus мера. 1. В строительном деле исходная единица измерения, устанавливаемая для данного сооружения или его частей. БАС 1. В архитектуре врач, зря быстрый свой успех, За модули ее принялся не на смех. Княжнин От дяди… … Исторический словарь галлицизмов русского языка
МОДУЛЬ — (1) числовое значение какой либо характеристики, единица меры, коэффициент, число, показатель какого либо соотношения, напр.: а) М. зубчатого зацепления отношение шага зубчатого зацепления к числу π; умножив модуль на число зубьев шестерни,… … Большая политехническая энциклопедия
МОДУЛЬ — (modulus) Величина числа с точки зрения его расстояния от 0. Модуль, или абсолютное значение реального числа х (обозначается |х|), является разностью между х и 0 независимо от знака. Следовательно, если х>0, то |х|=х и если х <0, то |х|=–х … Экономический словарь
Модуль — (М) – характеристика универсальности, представляющая собой предпочтительное число размера формообразующих элементов, как правило, 100 мм. Длина формообразующих элементов выбирается кратно 3 м. [ГОСТ Р 52086 2003] Модуль [лат. modulus мера]… … Энциклопедия терминов, определений и пояснений строительных материалов
МОДУЛЬ — в радиоэлектронике, функционально законченный узел радиоэлектронной аппаратуры, оформленный конструктивно как самостоятельное изделие. Чаще всего модуль печатная плата с размещенными на ней интегральными схемами и другими деталями. Применяется в… … Современная энциклопедия
МОДУЛЬ — комплексного числа см. Абсолютная величина. Модуль перехода от системы логарифмов при основании a к системе при основании b есть число 1/logab … Большой Энциклопедический словарь
Модуль — в рекламе определенные размеры графической рекламы для публикации в прессе. См. также: Реклама в СМИ Периодические издания Финансовый словарь Финам … Финансовый словарь
модуль — часть, устройство, узел Словарь русских синонимов. модуль сущ., кол во синонимов: 9 • веблет (1) • … Словарь синонимов
Модуль числа
Определение модуля числа
Алгебра дает четкое определение модуля числа. Модуль числа в математике — это расстояние от начала отсчёта до точки координатной прямой, соответствующей этому числу.
Если мы возьмем некоторое число «a» и изобразим его на координатной прямой точкой A — расстояние от точки A до начала отсчёта (то есть до нуля) длина отрезка OA будет называться модулем числа «a».
Знак модуля: |a| = OA.
Разберем на примере:
Точка В, которая соответствует числу −3, находится на расстоянии 3 единичных отрезков от точки O (то есть от начала отсчёта). Значит, длина отрезка OB равна 3 единицам.
Число 3 (длину отрезка OB) называют модулем числа −3.
Обозначение модуля: |−3| = 3 (читают: «модуль числа минус три равен трём»).
Точка С, которая соответствует числу +4, находится на расстоянии четырех единичных отрезков от начала отсчёта, то есть длина отрезка OС равна четырем единицам.
Число 4 называют модулем числа +4 и обозначают так: |+4| = 4.
Также можно опустить плюс и записать значение, как |4| = 4.
Онлайн-курсы математики для детей помогут подтянуть оценки, подготовиться к контрольным, ВПР и экзаменам.
Свойства модуля числа
Давайте рассмотрим семь основных свойств модуля. Независимо от того, в какой класс перешел ребенок — эти правила пригодятся всегда.
1. Модуль числа — это расстояние, а расстояние не может быть отрицательным. Поэтому и модуль числа не бывает отрицательным:
2. Модуль положительного числа равен самому числу.
3. Модуль отрицательного числа равен противоположному числу.
4. Модуль нуля равен нулю.
5. Противоположные числа имеют равные модули.
6. Модуль произведения равен произведению модулей этих чисел.
Геометрическая интерпретация модуля
Как мы уже знаем, модуль числа — это расстояние от нуля до данного числа. То есть расстояние от точки −5 до нуля равно 5.
Нарисуем числовую прямую и отобразим это на ней.
Эта геометрическая интерпретация используется для решения уравнений и неравенств с модулем. Давайте рассмотрим на примерах.
Решим уравнение: |х| = 5.
Мы видим, что на числовой прямой есть две точки, расстояние от которых до нуля равно 5. Это точки 5 и −5. Значит, уравнение имеет два решения: x = 5 и x = −5.
Решим неравенство: |a + 7|
График функции
График функции равен y = |х|.
Для x > 0 имеем y = x.
Этот график можно использовать при решении уравнений и неравенств.
Корень из квадрата
Оно равно a при а > 0 и −а, при а
Модуль рационального числа
Как найти модуль рационального числа — это расстояние от начала отсчёта до точки координатной прямой, которая соответствует этому числу.
Поиск ответа
| Вопрос № 293095 |
Здравствуйте! Грамотно ли писать и говорить «синтезаторные» вместо «синтетические»? Например, «синтезаторный модуль в программной ритм-машине» вместо «синтетический модуль в ритм-машине»?
Ответ справочной службы русского языка
Это слова с разными значениями, использовать одно вместо другого не получится.
Как правильно писать: резервный масштабируемый модуль или масштубируемый модуль (технический термин, сам модуль применяется в центрах обработки данных)?
Ответ справочной службы русского языка
Добрый день. На одном из сайтов увидела выражение » модуль нЫЙ оригами». Это верно?
Ответ справочной службы русского языка
Нет, оригами – существительное среднего рода.
Я занимаюсь разработкой технической документации. Столкнулся с такой проблемой.
В технических условиях на устройство написал:
. модуль МН-456 (далее по тексту изделие).
Надо ли писать далее в тексте изделие с большой буквы? Я считаю что нет. А вот директор требует писать далее по тексту с большой буквы.
Как правильно?
Ответ справочной службы русского языка
как пишется слово WI-FI модуль
Ответ справочной службы русского языка
Здравствуйте!
Ставится или не ставится запятая в предложениях? Никак не могу понять под какое правило пунктуации попадают данные предложения.
1. Нам очень нравится, когда пользователи быстро понимают (?) что такое LeaderTask.
2. Модуль статистики позволяет увидеть (?) на какие программы и сайты было потрачено время.
3. Для отображения сделанных дел и задач за определенный период (?) необходимо нажать на кнопку
4. Можно увидеть (?) на что тратится времени больше всего.
5. Попытайся объяснить (?) как ты этого добился.
6. Придет время и вы решите (?) что с ней делать.
7. Вы можете оценить (?) насколько мы близки к цели.
Ответ справочной службы русского языка
Во всех предложениях, кроме предложения 3, запятая ставится на основании одного и того же правила: в сложноподчиненном предложении запятая ставится между главным и придаточным предложением. В предложении 3 для постановки запятой оснований нет. В предложении 6 нужна еще запятая перед союзом и.
Добрый день! Прошу объяснить, что такое ПЛАГИН?
Это вопрос с Mozilla Firtfox.
Спасибо. Patrissiy.
Ответ справочной службы русского языка
Это один из крупнейших в Европе торгово-сервисный(ых) модуль (ей) нового поколения. Как правильно? И почему (очень нужно объяснение). Спасибо
Ответ справочной службы русского языка
как во множественном числе звучит слово крем и модуль
Ответ справочной службы русского языка
Ответ справочной службы русского языка
Вместо «рассчитана» следует написать «составлена». Что такое «- 5 пт»?
Спасибо за быстрый ответ на вопрос о склонении отрицательных величин (232770). Но объясните, пожалуйста, чем математическая операция обращения знака (минус) отличается от других математических операций, в которых мы точно склоняем признак соответствующей операции. Например, нет синусА пяти, нет модулЯ икс, нет пяти факториалА и т.д. Так по каким же нормам надо говорить нет минус пяти? Спасибо!
Ответ справочной службы русского языка
Добрый день. Корректно ли составлено следующее предложение, если нет, то как оно должно выглядеть? Модуль размещен в конце машины, а не так, как следует его размещать после последней секции. Заранее спасибо.
Ответ справочной службы русского языка
Ответ справочной службы русского языка
Допустимы оба варианта, предпочтителен второй.
Как правильно пишется слово «По модуль но»? Спасибо
Ответ справочной службы русского языка
В словарях это слово не зафиксировано, но с точки зрения орфографии Вы написали корректно.
Добрый день! Подскажите пожалуйста, правильно ли составлено предложение:» Модуль по работе с приемом и выдачей документов».
Ответ справочной службы русского языка
Не вполне ясно, что такое _ модуль _ в данном контексте, однако, скорее всего, верно: _ модуль для работы_.
Выразительный JavaScript: Модули
Содержание
Начинающий программист пишет программы так, как муравьи строят муравейник – по кусочку, без размышления над общей структурой. Его программы как песок. Они могут недолго простоять, но вырастая, они разваливаются.
Мастер-программист знает, когда нужна структура, а когда нужно оставить вещи в простом виде. Его программы словно глина – твёрдые, но податливые.
Мастер Юан-Ма, Книга программирования
У каждой программы есть структура. В частностях она определяется тем, как программист делит код на функции и блоки внутри этих функций. Программисты вольны в создании структуры своей программы. Структура определяется больше вкусом программиста, нежели функциональностью программы.
В случае больших программ отдельные функции уже теряются в коде, и нам необходима единица организации кода больших масштабов. Модули группируют программный код по каким-то определённым признакам. В этой главе мы рассмотрим преимущества такого деления и техники создания модулей в JavaScript.
Зачем нужны модули
Есть несколько причин, по которым авторы делят свои книги на главы и секции. Это помогает читателю понять, как построена книга, и найти нужные им части. Автору это помогает концентрироваться на каждой конкретной части. Преимущества организации программ в нескольких файлах, или модулях, примерно те же. Структуризация помогает незнакомым с кодом людям найти то, что им нужно, и помогает программистам хранить связанные друг с другом вещи в одном месте.
Некоторые программы организованы по модели обычного текста, где порядок следования чётко определён, и где читателю предлагается последовательное изучение программы и множество прозы (комментариев) для описания кода. Это делает чтение кода менее пугающим (а чтение чужого кода обычно пугает), но требует больших усилий при создании кода. Также такую программу сложнее менять, потому что части прозы связаны между собой сильнее, чем части кода. Этот стиль называется литературным программированием. Те главы книги, в которых обсуждаются проекты, можно считать литературным кодом.
Обычно структурирование чего-либо требует затрат энергии. На ранних стадиях проекта, когда вы ещё не уверены, что где будет, и какие модули вообще нужны, я пропагандирую бесструктурную минималистическую организацию кода. Просто размещайте все части там, где удобно, пока код не стабилизируется. Таким образом не придётся тратить время на перестановку кусков программы, и вы не поймаете себя в такую структуру, которая не подходит для вашей программы.
Пространство имён
У большинства современных ЯП есть промежуточные области видимости (ОВ) между глобальной (видно всем) и локальной (видно только этой функции). У JavaScript такого нет. По умолчанию, всё, что необходимо видеть снаружи функции верхнего уровня, находится в глобальной ОВ.
Загрязнение пространства имён (ПИ), когда не связанные друг с другом части кода делят один набор переменных, упоминалась в главе 4. Там объект Math был приведён в качестве примера объекта, который группирует функциональность, связанную с математикой, в виде модуля.
Хотя JavaScript не предлагает непосредственно конструкции для создания модуля, мы можем использовать объекты для создания подпространств имён, доступных отовсюду. А функции можно использовать для создания изолированных частных пространств имён внутри модуля. Чуть дальше мы обсудим способ построения достаточно удобных модулей, изолирующих ПИ при помощи базовых концепций языка.
Повторное использование
В проекте, не разбитом на модули, непонятно, какие части кода необходимы для конкретной функции. В моей программе, шпионящей за врагами (глава 9), я написал функцию чтения файлов с настройками. Если мне понадобится использовать её в другом проекте, я должен буду скопировать части старой программы, которые вроде бы связаны с этой функцией, в мой новый проект. А если я найду там ошибку, я её исправлю только в том проекте, над которым работаю в данный момент, и забуду исправить её во всех остальных.
Когда у вас будет множество таких сдублированных кусков кода, вы обнаружите, что тратите кучу времени и сил на их копирование и обновление. Если разместить связанные между собой части программ в отдельные модули, их будет проще отслеживать, исправлять и обновлять, потому что везде, где этот функционал потребуется, вы сможете просто загрузить этот модуль из файла.
Эту идею можно использовать ещё лучше, если чётко прописать взаимоотношения разных модулей – кто от кого зависит. Тогда можно автоматизировать процесс установки и обновления внешних модулей (библиотек).
Если ещё развить идею – представьте себе онлайн-сервис, который отслеживает и распространяет сотни тысяч таких библиотек, и вы можете искать нужную вам функциональность среди них, а когда найдёте – ваш проект автоматически скачает её.
И такой сервис есть! Он называется NPM (npmjs.org). NPM – онлайн-база модулей и инструмент для скачивания и апгрейда модулей, от которых зависит ваша программа. он вырос из Node.js, окружения JavaScript, не требующего браузера, которое мы обсудим в главе 20, но также может использоваться и в браузерных программах.
Устранение связей (Decoupling)
Ещё одна задача модулей – изолировать несвязанные между собой части кода так, как это делают интерфейсы объектов. Хорошо продуманный модуль предоставляет интерфейс для его использования вовне. Когда модуль обновляют или исправляют, существующий интерфейс остаётся неизменным, чтобы другие модули могли использовать новую, обновлённую версию без изменений в них самих.
Стабильный интерфейс не означает, что в него не добавляют новые функции, методы или переменные. Главное, что существующая функциональность не удаляется и её смысл не меняется. Хороший интерфейс позволяет модулю расти, не ломая старый интерфейс. А это значит – выставлять наружу как можно меньше внутренней кухни модуля, при этом язык интерфейса должен быть достаточно гибким и мощным для применения в различных ситуациях.
Интерфейсы, выполняющие простую задачу, вроде чтения настроек из файла, выходят такими естественным образом. Для других – к примеру, для редактора текстов, у которого есть множество разных аспектов, требующих доступа извне (содержимое, стили, действия пользователя и т.п.) интерфейс необходимо скрупулёзно продумывать.
Использование функций в качестве пространств имён
Функции – единственная вещь в JavaScript, создающая новую область видимости. Если нам нужно, чтобы у модулей была своя область видимости, придётся основывать их на функциях.
Обратите внимание на простейший модуль, связывающий имена с номерами дней недели – как делает метод getDay объекта Date.
Функция dayName – часть интерфейса модуля, а переменная names – нет. Но хотелось бы не загрязнять глобальное пространство имён.
Теперь names – локальная переменная безымянной функции. Функция создаётся и сразу вызывается, а её возвращаемое значение (уже нужная нам функция dayName) хранится в переменной. Мы можем написать много страниц кода в функции, объявить там сотню переменных, и все они будут внутренними для нашего модуля, а не для внешнего кода.
Подобный шаблон можно использовать для изолирования кода. Следующий модуль пишет в консоль значение, но не предоставляет никаких значений для использования другими модулями.
Этот код выводит квадрат сотни, но в реальности это мог бы быть модуль, добавляющий метод к какому-то прототипу, или настраивающий виджет на веб-странице. Он обёрнут в функцию для предотвращения загрязнения глобальной ОВ используемыми им переменными.
А зачем мы заключили функцию в круглые скобки? Это связано с глюком синтаксиса JavaScript. Если выражение начинается с ключевого слова function, это функциональное выражение. А если инструкция начинается с function, это объявление функции, которое требует названия, и, так как это не выражение, не может быть вызвано при помощи скобок () после неё. Можно представлять себе заключение в скобки как трюк, чтобы функция принудительно интерпретировалась как выражение.
Объекты в качестве интерфейсов
Представьте, что нам надо добавить ещё одну функцию в наш модуль «день недели». Мы уже не можем возвращать функцию, а должны завернуть две функции в объект.
Когда модуль большой, собирать все возвращаемые значения в объект в конце функции неудобно, потому что многие возвращаемые функции будут большими, и вам было бы удобнее их записывать где-то в другом месте, рядом со связанным с ними кодом. Удобно объявить объект (обычно называемый exports) и добавлять к нему свойства каждый раз, когда нам надо что-то экспортировать. В следующем примере функция модуля принимает объект интерфейса как аргумент, позволяя коду снаружи функции создать его и сохранить в переменной. Снаружи функции this ссылается на объект глобальной области видимости.
Отсоединяемся от глобальной области видимости
Такой шаблон часто используется в модулях JavaScript, предназначающихся для браузера. Модуль возьмёт одну глобальную переменную и обернёт свой код в функцию, чтобы у него было своё личное пространство имён. Но с этим шаблоном бывают проблемы, когда много модулей требуют одно и то же имя, или когда вам надо загрузить две версии модуля одновременно.
Подкрутив кое-что, мы можем сделать систему, разрешающую одному модулю обращаться к интерфейсному объекту другого, без выхода в глобальную ОВ. Наша цель – функция require, которая, получая имя модуля, загрузит его файл (с диска или из сети, в зависимости от платформы) и вернёт соответствующее значение с интерфейсом.
Этот подход решает проблемы, упомянутые ранее, и у него есть ещё одно преимущество – зависимости вашей программы становятся явными, и поэтому сложнее случайно вызвать ненужный вам модуль без чёткого его объявления.
Нам понадобятся две вещи. Во-первых, функция readFile, возвращающая содержимое файла в виде строки. В стандартном JavaScript такой функции нет, но разные окружения, такие как браузер или Node.js, предоставляют свои способы доступа к файлам. Пока притворимся, что у нас есть такая функция. Во-вторых, нам нужна возможность выполнить содержимое этой строки как код.
Выполняем данные как код
Есть несколько способов получить данные (строку кода) и выполнить их как часть текущей программы.
Самый очевидный – оператор eval, который выполняет строку кода в текущем окружении. Это плохая идея – он нарушает некоторые свойства окружения, которые обычно у него есть, например изоляция от внешнего мира.
Способ лучше – использовать конструктор Function. Он принимает два аргумента – строку, содержащую список имён аргументов через запятую, и строку, содержащую тело функции.
Это то, что нам надо. Мы обернём код модуля в функцию, и её область видимости станет областью видимости нашего модуля.
Require
Вот минимальная версия функции require:
Так как конструктор new Function оборачивает код модуля в функцию, нам не надо писать функцию, оборачивающую пространство имён, внутри самого модуля. А так как exports является аргументом функции модуля, модулю не нужно его объявлять. Это убирает много мусора из нашего модуля-примера.
При использовании такого шаблона модуль обычно начинается с объявления нескольких переменных, которые загружают модули, от которых он зависит.
У такого простого варианта require есть недостатки. Во-первых, он загрузит и выполнит модуль каждый раз, когда его грузят через require – если у нескольких модулей есть одинаковые зависимости, или вызов require находится внутри функции, которая вызывается многократно, будет потеряно время и энергия.
Это можно решить, храня уже загруженные модули в объекте, и возвращая существующее значение, когда он грузится несколько раз.
Вторая проблема – модуль не может экспортировать переменную напрямую, только через объект export. К примеру, модулю может потребоваться экспортировать только конструктор объекта, объявленного в нём. Сейчас это невозможно, поскольку require всегда использует объект exports в качестве возвращаемого значения.
Традиционное решение – предоставить модули с другой переменной, module, которая является объектом со свойством exports. Оно изначально указывает на пустой объект, созданный require, но может быть перезаписано другим значением, чтобы экспортировать что-либо ещё.
Сейчас у нас есть система модулей, использующих одну глобальную переменную require, чтобы позволять модулям искать и использовать друг друга без выхода в глобальную область видимости.
Такой стиль системы модулей называется CommonJS, по имени псевдостандарта, который первым его описал. Он встроен в систему Node.js. Настоящие реализации делают гораздо больше описанного мною. Главное, что у них есть более умный способ перехода от имени модуля к его коду, который разрешает загружать модули по относительному пути к файлу, или же по имени модуля, указывающему на локально установленные модули.
Медленная загрузка модулей
Хотя и возможно использовать стиль CommonJS для браузера, но он не очень подходит для этого. Загрузка файла из Сети происходит медленнее, чем с жёсткого диска. Пока скрипт в браузере работает, на сайте ничего другого не происходит (по причинам, которые станут ясны к 14 главе). Значит, если бы каждый вызов require скачивал что-то с дальнего веб-сервера, страница бы зависла на очень долгое время при загрузке.
Можно обойти это, запуская программу типа Browserify с вашим кодом перед выкладыванием её в веб. Она просмотрит все вызовы require, обработает все зависимости и соберёт нужный код в один большой файл. Веб-сайт просто грузит этот файл и получает все необходимые модули.
Второй вариант – оборачивать код модуля в функцию, чтобы загрузчик модулей сначала грузил зависимости в фоне, а потом вызывал функцию, инициализирующую модуль, после загрузки зависимостей. Этим занимается система AMD (асинхронное определение модулей).
Наша простая программа с зависимости выглядела бы в AMD так:
Функция define здесь самая важная. Она принимает массив имён модулей, а затем функцию, принимающую один аргумент для каждой из зависимостей. Она загрузит зависимости (если они уже не загружены) в фоне, позволяя странице работать, пока файло качается. Когда всё загружено, define вызывает данную ему функцию, с интерфейсами этих зависимостей в качестве аргументов.
Загруженные таким образом модули должны содержать вызовы define. В качестве их интерфейса используется то, что было возвращено функцией, переданной в define. Вот модуль weekDay:
Чтобы показать минимальную реализацию define, притворимся, что у нас есть функция backgroundReadFile, которая принимает имя файла и функцию, и вызывает эту функцию с содержимым этого файла, как только он будет загружен. (В главе 17 будет объяснено, как написать такую функцию).
Чтоб отслеживать модули, пока они загружаются, define использует объекты, описывающие состояние модулей, сообщает нам, доступны ли они уже, и предоставляет их интерфейс по доступности.
Функция getModule принимает имя и возвращает такой объект, и убеждается в том, что модуль поставлен в очередь загрузки. Она использует кеширующий объект, чтобы не грузить один модуль дважды.
Мы предполагаем, что загружаемый файл тоже содержит вызов define. Переменная currentMod используется, чтобы сообщить этому вызову о загружаемом объекте модуля, чтобы тот смог обновить этот объект после загрузки. Мы ещё вернёмся к этому механизму.
Функция define сама использует getModule для загрузки или создания объектов модулей для зависимостей текущего модуля. Её задача – запланировать запуск функции moduleFunction (содержащей сам код модуля) после загрузки зависимостей. Для этого она определяет функцию whenDepsLoaded, добавляемую в массив onLoad, содержащий все пока ещё не загруженные зависимости. Эта функция сразу прекращает работу, если есть ещё незагруженные зависимости, так что она выполнит свою работу только раз, когда последняя зависимость загрузится. Она также вызывается сразу из самого define, в случае когда никакие зависимости не нужно грузить.
Когда все зависимости доступны, whenDepsLoaded вызывает функцию, содержащую модуль, передавая в виде аргументов интерфейсы зависимостей.
Первое, что делает define, это сохраняет значение currentMod, которое было у него при вызове, в переменной myMod. Вспомните, что getModule прямо перед исполнением кода модуля сохранил соответствующий объект модуля в currentMod. Это позволяет whenDepsLoaded хранить возвращаемое значение функции модуля в свойстве exports этого модуля, установить свойство loaded модуля в true, и вызвать все функции, ждавшие загрузки модуля.
Этот код изучать тяжелее, чем функцию require. Его выполнение идёт не по простому и предсказуемому пути. Вместо этого, несколько операций должны быть выполнены в неопределённые моменты в будущем, что затрудняет изучения того, как выполняется этот код.
Настоящая реализация AMD гораздо умнее подходит к превращению имён модулей в URL и более надёжна, чем показано в примере. Проект RequireJS предоставляет популярную реализацию такого стиля загрузчика модулей.
Разработка интерфейса
Разработка интерфейсов – один из самых тонких моментов в программировании. Любую нетривиальную функциональность можно реализовать множеством способов. Поиск работающего способа требует проницательности и предусмотрительности.
Лучший способ познать значимость хорошего интерфейса – использовать много интерфейсов. Некоторые будут плохие, некоторые хорошие. Опыт покажет вам, что работает, а что – нет. Никогда не принимайте как должное плохой интерфейс. Исправьте его, или заключите в другой интерфейс, который лучше вам подходит.
Предсказуемость
Если программист может предсказать, как работает ваш интерфейс, ему не придётся часто отвлекаться и смотреть подсказку по его использованию. Постарайтесь следовать общепринятым соглашениям. Если есть модуль или часть языка JavaScript, которая делает что-то похожее на то, что вы пытаетесь реализовать – будет неплохо, если ваш интерфейс будет напоминать существующий. Таким образом, он будет привычен для людей, знакомых с существующим интерфейсом.
В поведении вашего кода предсказуемость также важна. Вас может постичь искушение сделать интерфейс слишком заумным якобы потому, что его удобнее использовать. К примеру, вы можете принимать любые виды типов и комбинаций аргументов и проделывать с ними «то, что надо». Или предоставлять десятки специализированных функций, которые предлагают незначительно отличающуюся функциональность. Это может сделать код, опирающийся на ваш интерфейс, немного короче, зато затруднить людям, работающим с ним, строить чёткую мысленную модель работы вашего модуля.
Компонуемость
Старайтесь использовать в интерфейсах настолько простые структуры данных, насколько это возможно. Делайте так, чтобы функции выполняли простые и понятные вещи. Если это применимо, делайте функции чистыми (см. Главу 3).
К примеру, частенько модули предлагают свою версию массивоподобных коллекций объектов со своим интерфейсом для подсчёта и извлечения элементов. У таких объектов нет методов map или forEach, и никакая функция, ожидающая настоящий массив, не сможет с ними работать. Это пример плохой компонуемости – модуль нельзя легко скомпоновать с другим кодом.
Примером может служить модуль для орфографической проверки текста, который может пригодиться в текстовом редакторе. Проверочный модуль можно сделать таким, чтобы он работал с любыми сложными структурами, используемыми самим редактором, и вызывал внутренние функции редактора для предоставления пользователю выбора вариантов написания. Если вы поступите таким образом, модуль нельзя будет использовать с другими программами. С другой стороны, если мы определим интерфейс модуля проверки, который принимает простую строку и возвращает позицию, на которой в строке есть возможная ошибка, а впридачу – массив предлагаемых поправок, тогда у нас будет интерфейс, который можно скомпоновать с другими системами, потому что строки и массивы всегда доступны в JavaScript.
Многослойные интерфейсы
Разрабатывая интерфейс для сложной системы (к примеру, отправка емейл), часто приходишь к дилемме. С одной стороны, не нужно перегружать пользователя интерфейса деталями. Не надо заставлять их изучать его 20 минут перед тем, как они смогут отправить емейл. С другой стороны, не хочется и прятать все детали – когда людям надо сделать что-то сложное при помощи вашего модуля, у них должна быть такая возможность.
Часто приходится предлагать два интерфейса: детализированный низкоуровневый для сложных ситуаций, и простой высокоуровневый для обычного использования. Второй можно построить на основе первого. В модуле для отправки емейлов высокоуровневый интерфейс может быть просто функцией, которая принимает сообщение, адрес получателя и отправителя, и отправляет письмо. Низкоуровневый должен давать доступ к заголовкам, приложенным файлам, HTML письмам и т.д.
Модули позволяют структурировать большие программы, разделяя код по разным файлам и пространствам имён. Если обеспечить их хорошо разработанными интерфейсами, их будет просто использовать, применять в других проектах и продолжать использовать при развитии и эволюции самого проекта.
Хотя JavaScript совершенно не помогает делать модули, его гибкие функции и объекты позволяют сделать достаточно неплохую систему модулей. Область видимости функций используется как внутреннее пространство имён модуля, а объекты используются для хранения наборов переменных.
Есть два популярных подхода к использованию модулей. Один – CommonJS, построенный на функции require, которая вызывает модули по имени и возвращает их интерфейс. Другой – AMD, использующий функцию define, принимающую массив имён модулей и, после их загрузки, исполняющую функцию, аргументами которой являются их интерфейсы.
Упражнения
Названия месяцев
Напишите простой модуль типа weekday, преобразующий номера месяцев (начиная с нуля) в названия и обратно. Выделите ему собственное пространство имён, т.к. ему потребуется внутренний массив с названиями месяцев, и используйте чистый JavaScript, без системы загрузки модулей.
Вернёмся к электронной жизни
Надеюсь, что глава 7 ещё не стёрлась из вашей памяти. Вернитесь к разработанной там системе и предложите способ разделения кода на модули. Чтобы освежить вам память – вот список функций и типов, по порядку появления:
Не надо создавать слишком много модулей. Книга, в которой на каждой странице была бы новая глава, действовала бы вам на нервы (хотя бы потому, что всё место съедали бы заголовки). Не нужно делать десять файлов для одного мелкого проекта. Рассчитывайте на 3-5 модулей.
Некоторые функции можно сделать внутренними, недоступными из других модулей. Правильного варианта здесь не существует. Организация модулей – вопрос вкуса.
Круговые зависимости
Запутанная тема в управлении зависимостями – круговые зависимости, когда модуль А зависит от Б, а Б зависит от А. Многие системы модулей это просто запрещают. Модули CommonJS допускают ограниченный вариант: это работает, пока модули не заменяют объект exports, существующий по-умолчанию, другим значением, и начинают использовать интерфейсы друг друга только после окончания загрузки.
Можете ли вы придумать способ, который позволил бы воплотить систему поддержки таких зависимостей? Посмотрите на определение require и подумайте, что нужно сделать этой функции для этого.

