Почему команды и события представлены отдельно?

в чем разница между командами и событиями в архитектурах, которые подчеркивают события? Единственное различие, которое я вижу, заключается в том, что команды обычно поступают/вызываются субъектами вне системы, тогда как события, похоже, поступают обработчиками и другим кодом в системе. Однако во многих примерах приложений, которые я видел, они имеют разные (но функционально похожие) интерфейсы.

6 ответов


команды могут быть отклонены.

событий произошло.

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

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

Я вижу, что команды обычно источник / вызывается субъектами за пределами система, тогда как события кажутся sourced обработчиками и другим кодом в система

Это еще одна причина, по которой они представлены отдельно. Концептуальная ясность.

команды и события являются сообщениями. Но на самом деле они являются отдельными понятиями, и понятия должны быть смоделированы явно.


после работы с некоторыми примерами и особенно презентацией Грега Янга (http://www.youtube.com/watch?v=JHGkaShoyNs) я пришел к выводу, что команды избыточны. Это просто события от вашего пользователя, они нажали эту кнопку. Вы должны хранить их точно так же, как и другие события, потому что это данные, и вы не знаете, хотите ли вы использовать их в будущем. Ваш пользователь добавил, а затем удалил этот элемент из корзины или, по крайней мере, пытаться. Позже вы можете использовать эту информацию, чтобы напомнить об этом пользователю позже.


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

скажем, например, что после создания клиента вы также хотите инициализировать некоторые значения учетных записей и т. д. После того, как клиент AR добавить событие в EventDispatcher и это получено CustomerCreatedEventHandler объекта, этот обработчик может вызвать отправку команды, которая будет выполнять все, что вы потребность и т. д.

кроме того, есть DomainEvents и ApplicationEvents. Различие просто концептуальное. Сначала вы хотите отправить все события домена (некоторые из них могут создавать события приложения). Что я имею в виду?

инициализация учетной записи после возникновения CustomerCreatedEvent является событием домена. Отправка уведомления по электронной почте клиенту является событием приложения.

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

Я обычно добавляю события к моему диспетчеру на Агрегатном корневом уровне. Эти события являются DomainEvents или ApplicationEvents. Может быть и то и другое, а может быть и много. Как только мой обработчик команд будет завершен, и я вернусь в стек к коду, который выполняет обработчик команд, я проверю своего диспетчера и отправлю любой другой DomainEvent. Если все пройдет успешно, я закрою сделку.

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

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

тогда у вас есть сагах.... но это WAYYYY вне сферы этого вопроса:)

имеет ли это смысл?


они представлены отдельно, потому что они представляют очень разные вещи. Как сказал @qstarin, команды-это сообщения, которые могут быть отклонены, и что при успехе будет произведено событие. Команды и события являются Dtos, они являются сообщениями, и они, как правило, выглядят очень похожими при создании и сущности, однако с тех пор, не обязательно.

Если вы беспокоитесь о повторном использовании, то вы можете использовать команды и события в качестве конвертов для вашего (messge) полезная нагрузка

class CreateSomethingCommand
{
    public int CommandId {get; set;}

    public SomethingEnvelope {get; set;}
 }

однако я хотел бы знать, почему вы спрашиваете :D ie у вас слишком много команд/событий?


в дополнение к концептуальным различиям, упомянутым выше, я думаю, что есть еще одно различие, связанное с общими реализациями:

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

команды может не быть обработано таким образом. Создатель команды обычно имеет доступ к предполагаемому исполнителю команды. Это может быть, например, в виде очереди сообщений исполнителю. Таким образом, команда предназначен для одного субъекта.


Я думаю, что что-то добавить к ответу Квентина-сэнтина в том, что они:

Инкапсулируйте запрос как объект, тем самым позволяя вам параметризовать клиенты с различными запросами, запросами очереди или журнала и поддержкой непоправимые операции.

источник.