Это вторая из серии статей, в которой рассматривается система типов Inversion of Coupling Control для композиции. В этой статье обсуждается более общая система типов модулей, чем в процедуре первого класса предыдущей статьи .
Примечание. Некоторые функциональные языки программирования также пытаются определять первоклассные модули. Модули первого класса, определенные в этой статье, создаются из инвертированных функций .
Первоклассная процедура
Напомним, что в последней статье тип процедуры первого класса определяется следующим образом. Обратите внимание, что мы исключаем тип зависимости, так как зависимости устанавливаются автоматически.
Джава
xxxxxxxxxx
1
FirstClassProcedureType {
2
Class<?> parameterType;
3
ContinuationType[] continuations;
4
}
5
6
ContinuationType {
7
String name;
8
Class<?> argumentType;
9
}
10
Это определяет Первоклассную Процедуру, чтобы иметь один входной параметр и несколько продолжений для дальнейшей композиции логики и обработки исключений.
Вам также может понравиться: Функция IoC для первоклассной процедуры
модуль
Наличие одного входа с несколькими выходами отлично подходит для методов, функций и т. Д., Заключенных в процедуры первого класса. Однако, когда системы растут, мы не хотим, чтобы сложность заставляла входы / выходы страдать аналогично повышенной сложности. Мы хотим, чтобы входы / выходы предоставляли интерфейс для инкапсуляции сложности модуля. Обратите внимание, что без инкапсуляции мы не получим возможность модулировать сложность приложения.
Чтобы включить интерфейс для модуля, давайте создадим следующие типы ввода / вывода:
Джава
1
InputType {
2
String name;
3
Class<?> parameterType;
4
}
5
OutputType {
7
String name;
8
Class<?> argumentType;
9
}
Чтобы понять, почему создаются эти типы, мы собираемся использовать визуальную конфигурацию Inversion of Coupling Control, чтобы лучше помочь нам понять, что происходит.
Следующая конфигурация модуля представляет один вход, обрабатываемый процедурой первого класса, которая отправляет свой результат на выход:
В приведенной выше конфигурации процедура первого класса инкапсулирована в модуле. Все, что раскрывается из модуля, это входы и выходы. В результате тип вышеупомянутого модуля будет следующим:
- Ввод с именем «Ввод» с параметром, переданным в процедуру первого класса
- Выход с именем «Выход» с аргументом, предоставленным результатом выполнения процедуры первого класса
Это, однако, обеспечивает небольшое улучшение интерфейса процедуры первого класса.
Что становится полезным, так это инкапсуляция нескольких первоклассных процедур для выполнения функциональности модуля:
Хотя в модуль была включена новая процедура, интерфейс модуля не изменился. Другие конфигурации, использующие Модуль, не будут знать о внутреннем добавлении другой Первоклассной Процедуры.
Нам также не нужно ограничиваться отдельными входами и выходами. Мы могли бы иметь произвольно сложный модуль, который имеет несколько входов и выходов:
Полученный модуль инкапсулировал детали, чтобы иметь следующий интерфейс:
- Вход «Вход»
- Вход «Вход-2»
- Выход «Выход»
- Выход «Выход-2»
- Выход «Выход-3»
Тип модуля
Полученный тип для Модуля следующий:
Джава
xxxxxxxxxx
1
SectionType {
2
InputType[] inputs;
3
OutputType[] outputs
4
}
Модуль (секция) имеет несколько входов и несколько выходов. Эти входы / выходы могут быть подключены к соответствующим выходам / входам других модулей.
Кроме того, модули могут сами содержать другие модули. Поскольку входы / выходы подключены для композиции, модули имеют такое же соединение входа / выхода, как процедуры первого класса. Следующая конфигурация демонстрирует встраивание модуля в начале этой статьи в другой модуль:
Будь то Модуль, содержащий одну Процедуру Первого Класса или две, Процедура Первого Класса инкапсулирована и не имеет значения в вышеуказанной конфигурации. Использование модуля только на входах / выходах, выставленных модулем. Остальная часть сложности модуля заключена в капсулу. Это позволяет модулировать сложность приложения.
Первоклассный модуль
Итак, упомянутое название - «Модули первого класса», но мы обсуждали только визуальное соединение модулей.
Чтобы по сути быть «Первоклассным», модуль должен быть присвоен переменной. Да, есть другие условия. Однако для меня это самый простой способ думать о чем-то, что является первоклассным.
Приведенная выше графическая конфигурация основана на разделах (модулях), которые конфигурируются вместе программно. Графическая конфигурация на самом деле является слоем над первоклассными модулями (разделами), чтобы облегчить понимание того, как приложение модульно.
Вы можете увидеть это в реализации OfficeFloor графической конфигурации, использованной выше в этой статье. Выше графическая конфигурация через активность. Деятельность - это конкретная специализация Раздела ( здесь источник ActivityLoaderImpl ). Упражнение переводит XML из графической конфигурации в создание разделов, первоклассных процедур, входов, выходов. Каждый из них в реализации Activity назначается переменным, хранится в структурах данных, передается в функции, возвращается из функций и т. Д. Это делает Раздел (Модуль) по существу «Первоклассным».
Этот интерфейс ввода / вывода, основанный на продолжениях, чрезвычайно гибок. Это настолько важно, что процедуры первого класса сами по себе являются просто специализированной реализацией раздела ( см. «MethodEmployer» ).
Резюме
Мы видели, как мы можем инкапсулировать процедуры первого класса в модулях первого класса и даже в модулях первого класса внутри себя.
Мы показали, как графическая конфигурация на самом деле использует природу «первого класса». Графическая конфигурация на самом деле является композицией более высокого уровня, которая обеспечивает оба:
- Легче понять модульность приложения
- Более быстрая настройка приложения (фактически просто нарисуйте линии для композиции)
Обратите внимание, что вполне возможно программно настроить наше приложение. Тем не менее, это требует понимания первоклассных процедур / модулей значительно глубже - гораздо больше, чем может потребоваться начинающим разработчикам.
Таким образом, графическая конфигурация модулей первого класса обеспечивает простоту построения модульных приложений. Это без необходимости иметь дело со сложностью базовых конструкций. Что-то, в чем другие стратегии композиции все еще имеют проблемы.
In the next article, we will look at how First-Class Modules can provide a composition of varying existing composition strategies. You may find that existing composition strategies only really consider programming in the small, rather than programming in the much larger — where First-Class Modules become a lot more effective in modularising and simplifying your applications.
Stay tuned!