Там, кажется, бесконечные путаницы о том, что команды должны или не должны возвращать значения. Я хотел бы знать, если путаница происходит просто потому, что участники не заявили о своем контексте или ситуации.
Вот несколько примеров путаницы...
Уди Дахан говорит, что команды-то "не возвращает ошибки для клиента", а в этой же статье он показывает схему, где действительно команды возвращают ошибки клиента.
Майкрософт Нажмите кнопку Store статье говорится, что "команда...не'т вернуть ответ", а потом идет на неоднозначное внимание:
опыт боя растет вокруг CQRS и некоторые практики консолидации и, как правило, становятся лучшими практиками. Отчасти вопреки тому, что мы только что сказал... Это распространенное мнение сегодня думаю, что обе команды дрессировщика и приложений должны знать, как операции транзакций пошел. Результаты должны быть известны...
Ну неужели обработчиков команд возвращаемых значений или нет?
Взяв пример с Джимми Богард'ы с "CQRS и мифы," Я думаю, что ответ(ы) на этот вопрос зависит от того, какие программные/контекстная и"Сектор" Вы говорите о:
+-------------+-------------------------+-----------------+
| | Real-time, Synchronous | Queued, Async |
+-------------+-------------------------+-----------------+
| Acceptance | Exception/return-value* | <see below> |
| Fulfillment | return-value | n/a |
+-------------+-------------------------+-----------------+
Команда "прием" в основном относится к проверке. Предположительно результаты проверки должны быть предоставлены одновременно вызывающий, будет ли команда "исполнения" это синхронно или в очереди.
Однако, похоже, многие практикующие Дон'т начать проверку в обработчик команды. Из того, что я'вэ видел, это либо потому, что (1) Они'ве уже нашли фантастический способ для выполнения проверки на уровне приложений (т. е. ASP.NET контроллер MVC проверки действительного состояния с помощью данных аннотаций) или (2) архитектура, которая предполагает, что команды передаются на (вне процесса) на автобусе или очереди. Эти последние формы асинхронности обычно Дон'т предлагаем синхронной семантики проверки или интерфейсы.
Короче говоря, многие дизайнеры, возможно, захотите обработчик команды, чтобы предоставить результаты проверки в качестве (синхронно) возвращаемое значение, но они должны жить с ограничениями, они асинхронность инструменты, которые они используют.
О том, что "исполнения" из команды, клиент, который выдал команду надо знать в scope_identity для вновь созданной записи или, возможно, непредставление информации, такие как "дебетовое сальдо счета&.и"
В режиме реального времени кажется, что возвращаемое значение имеет наибольший смысл; исключения не должны быть использованы для взаимодействия бизнес-результатов отказа. Однако, в "по очереди" в контексте...возвращаемые значения естественно не имеет смысла.
Это-то, где всех в заблуждение, пожалуй, можно резюмировать:
многие (большинство?) Практикующие CQRS и предположить, что они сейчас, или в будущем, включить механизм асинхронности или платформа (на автобусе или очереди), и таким образом заявляют, что обработчики команды не имеют возвращаемых значений. Тем не менее, некоторые практикующие не имеют никакого намерения использовать такой событийной конструкции, и поэтому они будут одобрить обработчиков команд, которые (синхронно) возвращаемые значения.
Так, например, я считаю, что синхронное (запрос-ответ) контекст был предположить, когда Джимми Богард, предлагаемые в этом образце интерфейс:
public interface ICommand<out TResult> { }
public interface ICommandHandler<in TCommand, out TResult>
where TCommand : ICommand<TResult>
{
TResult Handle(TCommand command);
}
Его Mediatr продукт, в конце концов, в памяти инструмента. Учитывая все это, я думаю, что причина Джимми осторожно взял время, чтобы произвести пустота, возвращение из команды был не потому, что "и обработчиков команд не должны возвращать значения," но вместо этого, потому что он просто хотел, чтобы его посредник классе, чтобы иметь последовательный интерфейс:
public interface IMediator
{
TResponse Request<TResponse>(IQuery<TResponse> query);
TResult Send<TResult>(ICommand<TResult> query); //This is the signature in question.
}
...хотя не все команды имеют значимое значение для возврата.
Я правильно захватывать, почему возникает путаница на эту тему? Что-то я'м не хватает?
Следуя советам в решении сложности в CQRS исполнителя Владик Khononov предполагает обработку команды можно вернуть информацию, относящуюся к ее результату.
без нарушения каких-либо [с CQRS] принципы, команду можно смело возвращать следующие данные:
- результат выполнения: успех или неудача;
- сообщения об ошибках или ошибок проверки, в случае сбоя;
- новый номер агрегата версии, в случае успеха;
эта информация может значительно улучшить опыт пользователей системы, потому что:
- вам не придется опрашивать внешнего источника, за результат выполнения команды, вы его сразу же. Это становится тривиальным, чтобы проверить команды, и для возвращения сообщения об ошибке.
- если вы хотите, чтобы обновить отображаемые данные, вы можете использовать новую версию агрегата, чтобы определить, является ли модель представления отражает выполнена команда или нет. Больше не показывать устаревшие данные.
Даниэль выступает Уиттакер возвращая себе "общий результат" и объект из обработчика команды, содержащей эту информацию.
Ну, обработчиков команд возвращаемых значений или нет?
Они не должны вернуться бизнес-данным, только мета-данные (в отношении успеха или неудачи выполнения команды). CQRS не является [распоряжаться][1] на более высокий уровень. Даже если бы вы сломали пуристов'правил и вернуть то, что вы вернетесь? В CQRS обработчик команд-это метод обслуживания приложение, которое загружает "совокупных" затем вызывает метод "совокупных", то он сохраняется в
совокупности`. В намерения команды обработчика-изменение "совокупных". Вы бы'т знаю, что вернуться, что бы быть независимым от абонента. Каждая команда обработчика абонент/клиент хотел бы знать кое-что о новом государстве.
Если выполнение команды блокирует (синхронно ака) тогда все что вам нужно знать, если ли команда выполнена успешно или нет. Затем, на более высоком уровне, вы бы запрос именно тем, что вам нужно знать о новом приложении'государство с помощью запроса-модель, которая лучше подойдет для ваших нужд.
Думать иначе, если вам что-то вернуть из обработчика команды, вы даете ему две обязанности: 1. изменение агрегатного состояния и 2. запрос чтения-модель.
Что касается команды проверки, существует как минимум два типа команд проверки:
Однако, если мы идем какой-то уровень, в презентации слоя(т. е.
рестконечная точка), клиент
прикладной уровень`, мы могли бы вернуть все, и мы не' нарушать правила, потому что конечные точки предназначены после использования, вы точно знаете, что вы хотите, чтобы вернуться после того, как команда выполнена, в каждом случае.
CQRS и распоряжаться как микросервисов и разложение класса: основная идея та же ("и, как правило, небольших связных модулей и"), но они лежат на разных семантических уровнях.
Точки CQRS-это сделать запись/разделение моделей чтения; такие низкоуровневые детали, такие как значение, возвращаемое определенный метод не имеет никакого значения.
Обратите внимание на следующие [Фаулер'С цитатой][1]:
изменение, которое вводит CQRS не является разбиение, что концептуальная модель на отдельные модели для обновления и отображения, которые оно ссылается как команда и запрос соответственно после словаря CommandQuerySeparation.
Это о модели, не методы.
Обработчик команды может вернуть все, за исключением моделей чтения: статус (успех/неудача), сгенерированных событий (он'основной целью команды кинологов, кстати: для создания событий для данной команды), ошибки. Обработчиков команд очень часто бросить исключение непроверенное, это пример выходных сигналов от обработчиков команд.
Кроме того, автор этого термина, Грег Янг, говорит, что команды всегда синхронизированы (в противном случае, это будет событие): https://groups.google.com/forum/#!тема/dddcqrs/xhJHVxDx2pM
Грег Янг
на самом деле я сказал, что асинхронное команда не'т существуют :) на самом деле еще одно событие.
[1]: https://martinfowler.com/bliki/CQRS.html на "тесты"и
Ответ для @Galbenu Константин, я столкнулся с лимитом.
@мизантроп и что именно вы делаете с этими событиями?
@Galbenu Константин, в большинстве случаев, я не'т нуждаются в них как результат команды, конечно. В некоторых случаях -- я должен уведомить клиента в ответ на этот запрос API.
Это'ы очень полезно, когда:
И я могу предоставить пример для второго случая. Представьте, что мы делаем трут-как Служба, у нас есть команда LikeStranger. Эта команда может привести к StrangersWereMatched если нам нравится человек, который уже любил нас. Мы должны уведомить мобильный клиент в ответ, будет ли матч или нет. Если вы просто хотите проверить matchQueryService после выполнения команды, вы можете найти матч, но нет никакой гарантии, что матч был случилось сейчас, потому что иногда трут-шоу уже подобраны незнакомых людей (видимо, в безлюдных местах, может быть, непоследовательность, наверное, у тебя просто 2-го устройства и т. д.).
Проверки ответа, если StrangersWereMatched действительно произошло сейчас, это так просто:
$events = $this->commandBus->handle(new LikeStranger(...));
if ($events->contains(StrangersWereMatched::class)) {
return LikeApiResponse::matched();
} else {
return LikeApiResponse::unknown();
}
Да, вы можете ввести команду ID, к примеру, и сделать матч читать модели, чтобы сохранить его:
// ...
$commandId = CommandId::generate();
$events = $this->commandBus->handle(
$commandId,
new LikeStranger($strangerWhoLikesId, $strangerId)
);
$match = $this->matchQueryService->find($strangerWhoLikesId, $strangerId);
if ($match->isResultOfCommand($commandId)) {
return LikeApiResponse::matched();
} else {
return LikeApiResponse::unknown();
}
... но думать об этом: почему вы считаете, что первый пример с простой логикой хуже?
Это не'т нарушать CQRS и в любом случае, я просто сделал неявное явным.
Это неизменный подход без гражданства. Меньше шансов, чтобы поразить ошибки (например, если matchQueryService
кэшируется/задержки [не мгновенно последовательное], у вас есть проблемы).
Да, когда сам факт сопоставления недостаточно и необходимо получить данные для получения ответа, вы должны использовать службу запросов. Но ничто не мешает вам получать события из обработчика команды.