Сегодня поговорим об архитектуре бэкенд-приложений и сравним два популярных способа структурирования проектов: onion и DDD. Расскажу о преимуществах второго подхода перед первым и своём недавнем опыте перевода проекта на гексагональную архитектуру. Этот текст для тех, кто уже работал со слоистой архитектурой и хочет большего(например, начать работать с микросервисами).
Начнем со слоистой архитектуры. Слоистая, она же луковичная архитектура - это архитектура, в которой мы делим всё приложение на слои. Каждый слой имеет свою функцию, своё четкое назначение. Например, взаимодействие с базой данных: в таком слое должны находиться исключительно функции для взаимодействия с базой данных, и больше ничего. Не должно быть взаимодействия с клиентом или ещё каких-то функций.
Часто в слоистой архитектуре на бэкенде 3 основных слоя: для взаимодействия с хранилищем, логики приложения и представительный слой.
Вот типичная трёхслойная архитектура, в ней всё достаточно просто. Запрос проходится по всем слоям, приобретая конечную форму(запрос в хранилище), ответ делает обратный путь, превращаясь уже в какой-нибудь удобный для клиента формат(JSON, XML и тд).
Такую архитектуру я довольно долго использовал во всех своих проектах и в стартапе, в котором принимаю участие. В маленьких пет-проектах такой подход действительно работает и не приносит проблем, но в проектах побольше начинается гемор.
Один из главных принципов слоистой архитектуры - возможность замены любого слоя на аналогичный так, чтобы ни один другой слой вообще не нужно было бы менять. Но в реальности чем больше сущностей появляется в проекте, тем сложнее его соблюдать.
Сначала появляется слишком много зависимостей, и становится всё труднее их контролировать. Отсюда вытекает запущенность монолита(ведь onion - это монолитная архитектура). Нагрузка распределяется неправильно, и приложение испытывает перегрузки. Дальше слои начинают смешиваться - логику приложения выделить всё сложнее. Всё труднее становится расширять приложение, из-за зависимостей отладка превращается в ад, и разработка сильно замедляется. Масла в огонь подливают строгие архитектурные паттерны, которые ограничивают возможности разработчика. Если вы читаете этот текст, то наверняка с этим уже столкнулись. Такая же ситуация сложилась и в нашем проекте.
Очевидно, что в такой ситуации необходим распил монолита, переход на другую архитектуру и внедрение более свободных паттернов. Мы выбрали DDD, это казалось очевидным решением. DDD (Domain Driven Design, hexagonal architecture) - микросервисная(хотя её можно использовать как монолитную) архитектура, построеная на абстракциях. Если у вас есть опыт работы только со слоистой архитектурой, то в качестве грубого примера можете представить себе ту же трёхслойную архитектуру, где вместо слоя взаимодействия с хранилищем есть слой взаимодействия вообще со всеми технологиями, а ещё есть отдельный слой с абстракциями. Абстракции - вообще главное, что есть в DDD. Эти абстракции, а ещё вспомогательные инструменты и демонстрационные сущности(шаблоны, схемы) отделяются от приложения, и в итоге архитектура выглядит так:
Главное преимущество гескагональной архитектуры перед слоистой - расширяемость. Гораздо проще внедрить новые фичи, новые параметры и новые функции, потому что зависимостей меньше.
Сначала такая структура казалась мне вообще нелогичной, но в процессе перехода на DDD я обнаружил, что писать стало гораздо легче, потому что инфраструктура была полностью вынесена даже из низшего слоя приложения, а зависимостей стало меньше. Появилось даже какое-то иррациональное облегчение и внезапная свобода действий над каждой сущностью. Такой подход мне теперь кажется даже более логичным, чем слоистая архитектура.
Но нужно помнить, что такая архитектура не имеет смысла, если в проекте 2-3 сущности, потому что DDD используется преимущественно как микросервисная архитектура в приложениях с большим количеством зависимостей, чего просто не может быть в маленьких пет-проектах на 2-3 сущности. Где-то даже достаточно простой линейной архитектуры. Да и вообще использование разных технологий и практик просто так, без необходимости - плохая практика, если только вы не решили поэкспериментировать, чтобы научиться.
P.S. И надо сабнуться на тгк: https://t.me/dmkjfss
Top comments (0)