Pull to refresh
8K+
2
7
Rating
Send message

Из схемы модуля видно что при обращении к модулю идёт вызов к Anti-Corruption Layer, а не к менеджеру модуля.

В тексте и изображении схемы всё верно. При обращении к другому модулю ACL нашего модуля вызывает их менеджер.

Anti-Corruption Layer скорее всего это и есть слой Presentation

Слой Presentation о другом: он содержит view-хи и прочие представления данных. Задача ACL создать собственный dto, класс которого расположен у нас, в нашем модуле. Это позволяет использовать его у себя в модуле без порождения внешних зависимостей. Такой подход дополнительно обеспечивает безопасность от изменений в других модулях: у них в ответе от менеджера 10 свойств, мы используем только 2, любые изменения остальных 8 никак не отразятся на нашем модуле. Оставшиеся 2 свойства, которые используются, не дадут повредить статические анализаторы.

Ещё один плюс такого подхода, который хочется отметить, это то, что все “мапперы”, реализующие ACL, располагаются системно. Всегда знаешь где их искать у себя и в других модулях. Узнать список модулей, от которых зависит твой, просто и быстро.

Непонятно что именно понимается под блоком Components и где находится блок доменной логики? 

Components и есть блок доменной логики. Как видно из схемы, блоки Components, Dto, Models и прочие расположены внутри объединяющего их, группирующего блока Domain. Все они находятся внутри директории Domain каждого модуля.

Наоборот, благодаря такому подходу кода в файлах становится меньше. Внутри одного модуля мы используем не один глобальный менеджер, а несколько небольших.

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

Спасибо за комментарий! Давайте по порядку.

убрать 1 слой, чтобы добавить его в доменный

Мы взяли классический Onion лишь за основу и адаптировали его под реалии Flowwow. В итоге у нас получилась своя архитектура: слой Application заменил Infrastructure, став публичным.

Мы не переносили Infrastructure в доменный слой — мы от него полностью отказались. Точкой входа и границей модуля стал Application. Да, в некоторых модулях внутри приватной области можно встретить раздел Infrastructure, но он несет совершенно другой смысл. Там мы пишем “провайдеры” для связи со сторонними внешними сервисами.

Как видится мне - разделением на модули вы получаете дублирование кода

Дублирование кода сведено к минимуму благодаря жесткому разделению предметных областей. Команда товаров занимается только товарами, команда гео — картами. Им концептуально негде написать один и тот же код.

у вас на каждый юзер кейс сколько обращений к базе?

Количество обращений к БД зависит от задачи: где-то хватает одного, где-то их десятки. Как правило такие сложные процессы уходят в очередь и выполняются постепенно

У каждого модуля свои обращения? А как на счёт сложных join запросов?

Каждый модуль работает только со своими таблицами в базе, через модели, расположенные внутри модуля. Эти модели не дублируются в других модулях. Получить от них данные можно только через менеджеры. Да и сами модели менеджеры не вернут, они преобразуют их в DTO.
Сложные join разрешаем по разному: иногда, в рамках одного контекста, когда обе таблицы ему принадлежат, прописываем связи между моделями, как заложено в ActiveRecord. В других случаях, когда модели из разных контекстов, рассматриваем отдельно. 

Зачастую связи прописывать не нужно вовсе, подобные задачи решаются в несколько запросов: достаточно отдельно получить id из одной таблицы и добавить их в запрос к другой, а вторым запросом, уже в своем модуле, можно получить результат. Только в исключительных, редких кейсах, когда действительно нужна оптимизация, мы договариваемся о применении прямых запросов к базе. Что согласовывается с архитектором, либо DBA командой отдельно.

разве много бизнес задачи которые затрагивают 1 конкретный модуль? Большинство задач превращается в тим билдинги?

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

Любой модуль при необходимости можно вынести в отдельный сервис без радикальной переработки.

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

Я очень сильно надеюсь что вы здесь не про инверсию зависимостей

Да, в тексте описано направление подключения классов. О том, что обращение к модулю опирается на application, а он на domain, только в таком порядке.

Information

Rating
1,081-st
Registered
Activity