Статьи
November 19, 2023

Микроядерная (microkernel) архитектура

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

Описание паттерна

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

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

Рисунок 3-1. Схема архитектуры микроядра

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

Ядро системы должно знать, какие подключаемые модули доступны и как к ним обращаться. Одним из распространенных способов реализации этого является использование некоторого реестра подключаемых модулей. В этом реестре содержится информация о каждом подключаемом модуле, включая его имя, контракт на передачу данных и данные о протоколе удаленного доступа (в зависимости от того, как подключаемый модуль связан с основной системой). Например, подключаемый модуль для налогового программного обеспечения, который отмечает элементы налогового аудита, представляющие повышенный риск, может иметь запись в реестре, содержащую имя сервиса (AuditChecker), контракт с данными (входные и выходные данные) и формат контракта (XML). Кроме того, она может содержать WSDL (Web Services Definition Language), если доступ к плагину осуществляется по протоколу SOAP.

Подключаемые модули могут быть связаны с основной системой различными способами, включая OSGi (open service gateway initiative), обмен сообщениями, веб-сервисы или даже прямое связывание "точка-точка" (т.е. инстанцирование объектов). Тип используемого соединения зависит от типа создаваемого приложения (небольшой продукт или крупное бизнес-приложение) и конкретных потребностей (например, одиночное или распределенное развертывание). Сам архитектурный паттерн не оговаривает никаких деталей реализации, только то, что подключаемые модули должны оставаться независимыми друг от друга.

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

Примеры паттерна

Пожалуй, лучшим примером архитектуры микроядра является среда разработки Eclipse. Загрузив базовый продукт Eclipse, вы получаете не более чем модный редактор. Однако, если начать добавлять подключаемые модули, он становится очень настраиваемым и полезным продуктом. Интернет-браузеры - еще один распространенный пример продукта, использующего архитектуру микроядра: программы просмотра и другие подключаемые модули добавляют дополнительные возможности, которых нет в базовом браузере (т.е. в ядре системы).

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

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

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

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

Рисунок 3-2. Пример архитектуры микроядра

Продолжение следует...

Перевод книги "Software Architecture Patterns".