Шаблон портов и адаптеров (шестиугольная архитектура)
2019-10-21 14:51:12 +0600 +0600
Hexagonal Architecture
Немного истории Шаблон портов и адаптеров (шестиугольная архитектура)
Алистер Кокберн изобрел его в 2005 году. Это ответ на желание создать тщательно проверяемые приложения. Как говорит Кокберн: «Позвольте приложению в равной степени управляться пользователями, программами, автоматизированными тестовыми или пакетными сценариями, а также разрабатываться и тестироваться изолированно от возможных устройств времени выполнения и баз данных».
Зачем solution architect должен знать о Hexagonal Architecture
-
Если 100% покрытие кода модульного теста важно для вашего приложения.
-
Если вы хотите иметь возможность переключать свой механизм хранения или любой другой тип стороннего кода.
-
Если вы пишите долгосрочные приложения, которые должны идти в ногу с изменяющимися требованиями.
Что такое Архитектура портов и адаптеров
Основная цель этой архитектуры - отделить основную логику приложения от сервисов, которые оно использует. Это позволит «подключать» различные сервисы и запускать приложение без этих сервисов.
Основная логика или бизнес-логика приложения состоит из алгоритмов, которые необходимы для достижения бизнес цели. Алгоритмы реализуют сценарии использования, являющиеся ядром приложения. Когда они меняются, меняется и суть самого приложения.
Сервисы не являются необходимыми. Они могут быть заменены без изменения цели приложения. Примеры: доступ к базе данных и другие типы хранилищ, компоненты пользовательского интерфейса, электронная почта и другие компоненты связи, аппаратные устройства.
В строгом смысле этой архитектуры даже инфраструктура приложения представляет собой набор сервисов. Основная логика приложения не должна зависеть от этих сервисов в этой архитектуре (так что она становится «независимой от фреймворка»).
Преимущества такой архитектуры:
- Логика ядра может быть протестирована независимо от внешних сервисов.
- Сервисы легко заменить другими, более подходящими с учетом меняющихся требований.
Для того чтобы дальше говорить про данный подход к архитектуре надо ввести два понятия:
- Порт
- Адаптер
Порт - это точка входа, обеспечиваемая базовой логикой. Он определяет набор функций. Например REST endpoint.
Первичные порты являются основным API приложения. Они вызываются первичными адаптерами, которые формируют пользовательскую часть приложения. Примерами основных портов являются функции, которые позволяют изменять объекты, атрибуты и отношения в основной логике.
Вторичные порты являются интерфейсами для вторичных адаптеров. Они вызваны основной логикой. Примером вторичного порта является интерфейс для хранения отдельных объектов. Этот интерфейс просто указывает, что объект должен быть создан, извлечен, обновлен и удален. Он ничего не говорит о том, как хранится объект.
Если попробовать проще объяснить то: Первичный порт говорит системе что она должна сделать. Вторичный порт передает команду от нашей системы, стороннему сервису.
Адаптер - это мост между приложением и службой, который требуется приложению. Адаптер всегда соответствует определенному порту.
Первичный адаптер - это фрагмент кода между логикой пользователя и ядром.
Один адаптер может быть функцией модульного тестирования для логики ядра. Другой может быть функция, подобная контроллеру, которая взаимодействует как с графическим интерфейсом пользователя, так и с базовой логикой. Первичный адаптер вызывает функции API базовой логики.
Вторичный адаптер является реализацией вторичного порта (который является интерфейсом).
Например, это может быть небольшой класс, который преобразует запросы хранения приложения в заданную базу данных и возвращает результаты базы данных в формате, запрошенном вторичным портом. Это также может быть мок объект базы данных, необходимый для модульного тестирования определенных частей логики ядра. Базовая логика вызывает функции вторичного адаптера.
как работает
-
Приложение может использоваться различными типами пользователей. Каждый из них может создать свой собственный вариант приложения, подключив пользовательские адаптеры.
-
Создается экземпляр приложения, а также адаптеры.
-
Вторичные адаптеры передаются в основную логику (dependency injection).
-
Первичные адаптеры получают ссылку на ядро логики. Они начинают управлять приложением.
-
Пользовательский ввод обрабатывается одним или несколькими основными адаптерами и передается в основную логику.
-
Основная логика взаимодействует только со вторичными адаптерами.
Почему шестиугольник ?
Шаблон Ports & Adapters изображает приложение в виде замкнутой области.
Закрытая область, выбранная Алистером Кокберном для рисования приложения, представляла собой шестиугольник, поэтому этот шаблон также называется гексагональной архитектурой.
От себя хочу сказать, что умные дядьки дизайнеры например Артемий Лебедев, часто говорят: Для того что бы показать стабильность и надежность компании, необходимо логотипы делать в виде жестких фигур и многогранников(треугольник , квадрат…). Шестиугольник одна из самых многогранных фигур.
Шестиугольник содержит бизнес-логику, без ссылок на какие-либо технологии, рамки или устройства реального мира. Таким образом, приложение не зависит от технологии. Может быть так автор методики хотел явно указать изолированность системы от ее интеграций.
Шаблон Ports & Adapters ничего не говорит о структуре внутренней части шестиугольника. У вас могут быть слои … вы можете иметь компоненты по функциям … вы можете иметь спагети-код … вы можете иметь большой шарик грязи … вы можете применять тактические схемы DDD … вы можете иметь один CRUD … все зависит от вас.
ЧТО МОЖНО почитать
http://www.dossier-andreas.net/software_architecture/ports_and_adapters.html
https://softwarecampament.wordpress.com/portsadapters/
https://herbertograca.com/2017/09/14/ports-adapters-architecture/