Обновить
6
0
Alexey Skripka @AlexViolin

c# / sql developer

Отправить сообщение

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

В указанной автором статьи книге авторов Гарри Персиваль, Боб Грегори в итоговой общей схеме архитектуры почему-то выпала связь между блоком обработчиков (handlers) и предметной областью (domain). Эта связь многократно указана в книге - например в рисунке 7.5. Но в итоговой схеме её нет. Если приложение содержит функционал домена (предметную область), то нельзя обойтись без связки handlers -> domain.

Каким образом принцип наименьшего действия Лагранжа связан с нейросетью? Там классическая механика (набор материальных точек с ненулевой массой) с набором законов сохранения. Как это переносится на нейросеть?

Это как усечённый вариант космического туризма от Безоса. Тот поднимает на 100 км, а здесь не более 10 км.

Меня давно интересовал случай, когда в саге упадёт откат одной из транзакций - тогда и "eventual consistency" не удастся достигнуть. Поэтому при работе например с деньгами никак нельзя уйти от two-phase commit или работать только с одной бд (но такое часто бывает невозможно).

Юз кейс принадлежит слою application logic, который находится выше слоя доменной логики. Домен ничего не знает про юз кейс, который его использует.

Мне кажется наиболее логичным вложить функционал, реализованный в CrossDomainCoordinator, в юз кейс "Отменить заказ" в виде метода или вложенного объекта.

Можно и другое вспомнить. По просьбам трудящихся расстрелять врагов народа, как бешенных собак.

Однако как возрос накал в обсуждении. За цитату из Фаулера уже ставят минус!!!

  1. Потащим ли мы вызов из одного адаптера в другой через сервисный слой?

Из Вашего рисунка это как раз отлично видно, что запрос из входного адаптера всегда проходит через сервисный слой в исходящий адаптер. Мой вопрос как раз в другом - допускает ли такая архитектура при необходимости прямое обращение из входного адаптера (визуальная форме) к исходящему адаптеру (DocumentRepository)?

Рисунок, приведенный в разделе "Структура" данной статьи, по сути является квинтэссенцией написанного по архитектуре за последние 20 лет. Но всегда можно найти неприятные вопросы, которые портят такую стройную схему.
Рассмотрим приложение с визуальным интерфейсом. То есть входным адаптером будет визуальная форма. Конечным хранилищем данных является база данных.

На визуальной форме вводятся данные для новой сущности "Документ", которая сохраняется в таблицу Documents базы данных. Бизнес-логика приложения предполагает, что название каждого документа (поле Title в таблице Documents) является уникальным в рамках этой таблицы. То есть перед сохранением нового документа в бд его надо валидировать путём запроса к бд на предмет уникальности названия документа в рамках поля Title таблицы Documents.

Вопрос - этот запрос к бд Вы протяните с визуальной формы через всю цепочку слоёв или напрямую с визуальной формы обратитесь к DocumentRepository?

Это правило предполагает, что взаимодействие между слоями происходит однонаправленно и нижележащий слой не видит вышележащий слой. И соответственно нижележащий слой не видит модель данных вышележащего слоя.

При этом вы так не ответили на вопрос, откуда вы взяли, что DTO не должно быть в слое бизнес-логики.

Это правило по которому строю архитектуру. Нет никаких причин, чтобы другие разработчики делали так же.

Прочитайте мой комментарий внимательно.

данные ArticleDTO можно передать сразу в объект типа Article. Это объект articleFromDTO. 

Как пример рассмотрю use case редактирования статьи. Use case требует соблюдение бизнес-правила - "если статья в статусе "На модерации", ее нельзя редактировать,то есть записывать новые значения в поля Text и Title."

При построении многослойной архитектуры буду придерживаться книги Фаулера "Шаблоны корпоративных приложений".

Верхний слой приложения - это набор веб-контроллеров, которые обрабатывают запрос от внешнего консюмера и отправляют ему ответ.

Ниже слой логики - logic layer. Он состоит из двух подслоёв - верхнего application logic и нижнего domain logic.

Самый нижний слой - persistence layer отвечает за взаимодействие с реляционной базой данных.
Взаимодействие между слоями однонаправленное - от вышележащего к нижележащему.

Модель данных верхнего слой - набор DTO объектов. В текущем примере это класс ArticleDTO.

Модель данных слоя логики - набор доменных объектов - сущностей и объектов-значений. В текущем примере это класс ArticleEntity. Но для рассматриваемого use case он не понадобится.

Модель данных слоя persistence layer - это объекты, которые мапятся на таблицы реляционной базой данных. В текущем примере класс Article. Он соответствует записи в таблице tblArticles в базе данных.

Для работы со нужной статьёй идёт сквозная связь от контента веб-запроса, через модели данных всех слоёв и до таблицы tblArticles в базе данных через идентификатор статьи Id.

Далее по пунктам рассмотрю работу функционала для use case редактирования статьи.

  1. Внешний консюмер делает запрос на изменение данных статьи, который обрабатывает веб-контролер. Данные запроса помещаются в объект ArticleDTO.

  2. Веб-контролер вызывает функционал объекта application logic типа UpdateArticleUsecase. В общем случает данные из ArticleDTO надо передать в ArticleEntity, но в данном use case этот объект будет излишен и данные ArticleDTO можно передать сразу в объект типа Article. Это объект articleFromDTO. Ссылка на этот объект находится в объекте типа UpdateArticleUsecase.

  3. Далее должна пройти валидация - то есть сравнение полей Title и Text в articleFromDTO с такими же полями статьи, которые хранятся в базе данных. Значение Id статьи в articleFromDTO идентично значению в поле Id в таблице tblArticles в базе данных.

  4. Объект-валидатор является элементом доменной логики, которая включает объекты-сущности, объекты-значения, доменные сервисы и валидаторы доменных объектов.
    Объект типа UpdateArticleUsecase создаёт объект валидатора, передаёт ему ссылку на объект articleFromDTO и запускает метод валидатора Validate().
    Валидатор реализует бизнес-правило - нельзя редактировать статью в статусе "На модерации", то есть записывать новые значения в поля Text и Title. Функционал валидатора проверяет значение поля Status объекта articleFromDTO. Если статус не "На модерации", то метод Validate() возвращает true и валидация успешно пройдена. Если статус "На модерации", то валидатор обращается к функционалу persistence layer для получения объекта типа Article из бд по значению, которое берётся из поля Id объекта articleFromDTO. В полученном из persistence layer объекте articleFromDatabase валидатор сравнивает поля Text и Title с такими же полями в articleFromDTO. При идентичности соответствующих полей метод Validate() возвращает true и валидация успешно пройдена. В противном случае метод Validate() возвращает false и валидация не пройдена.

  5. В случае успешной валидации объект типа UpdateArticleUsecase передаёт articleFromDTO в persistence layer для обновления данных статьи в базе данных. Если валидация не пройдена объект типа UpdateArticleUsecase генерирует Exception с текстом сообщения об ошибке.

Вызов функционала DAO объектов происходит из слоя вышележащего относительно persistence layer. В этом вышележащем слое как открывается транзакция, в рамках которой выполняются запросы к бд, так и обрабатываются ошибки запросов к бд. Если в рамках одного use case идёт обновление данных сразу в нескольких базах данных, то решения этой задачи известные и достаточно сложные - или настройка распределённой транзакции в рамках операционной системы компьютера или настройка механизма SAGA. Работа с обновлением данных в рамках SAGA выходит далеко за рамки того, что описано в данной статье.

Если есть сущность Клиент, то вложенный в него адрес клиента в виде Value Object, это совершенно нормальное решение.

"Перенос данных из DTO в сущность" это перенос данных между моделями данных слоя контроллеров и слоя сервисов. Это перенос данных двунаправленный. Бизнес-логика - это функционал слоя сервисов.

DTO никак не может быть частью домена. Это совершенно разные слои приложения.

Если чётко разделять приложения на слои и к каждому слою привязывать свою модель данных, то слой сервисов не должен ничего знать о существовании DTO объектов. Именно контроллер должен переносить данные из DTO в объект модели данных с которой работает слой сервисов.

1
23 ...

Информация

В рейтинге
6 416-й
Зарегистрирован
Активность