Доменные события требуют класса или темы?

Должны ли события домена отправляться в соответствии с классами событий или классами и темой?

Например, у меня есть следующее событие:

class UserRegisteredEvent implements INonTransactionalEvent{
    public Timestamp: TTimestamp;
}

И менеджер событий,

class EventManager {
   /** Omitted **/
}

Уди Даан предлагает, чтобы события были первоклассными объектами, и мне это нравится. Существует объект UserRegisteredEvent, объект OrderComplete. Мой вопрос: привязывает ли сам тип к обработчикам событий? Например, я должен просто передать объект события методу публикации?

EventManager.Publish(new UserRegisteredEvent(1));

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

EventManager.Publish(new UserRegisteredEvent(1), Events.UserRegistered)

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

EventManager.UserRegisteredEvent(1)

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

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

2 ответа

Решение

Доменные события на самом деле не требуют конкретной реализации. В конце концов они просто семантические DTO. Я не понимаю, чего вы пытаетесь достичь, но если вы не строите служебную шину, вы просто отправляете объект события для обработки любыми настроенными обработчиками.

Событие не знает об обработчиках, обработчики не знают друг о друге, шина знает, как отправить событие обработчикам. И вы хотите, чтобы обработчик явно обрабатывал только 1 событие, SRP . Вы можете объединить реализации связанных обработчиков в один класс, но это деталь реализации.

Если вы действительно хотите вводить темы, я бы сделал это через наследование интерфейса. Например:

interface IUserEvent : INonTransactionalEvent { ... }

class UserRegisteredEvent implements IUserEvent {
    public Timestamp: TTimestamp;
}

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

Другие вопросы по тегам