域事件需要课程还是主题?

时间:2014-06-23 10:11:44

标签: events domain-driven-design domain-events eda

是否应根据事件类,类或主题调度域事件?

例如,我有以下事件:

class UserRegisteredEvent implements INonTransactionalEvent{
    public Timestamp: TTimestamp;
}

还有一位活动经理,

class EventManager {
   /** Omitted **/
}

Udi Dahan建议事件是头等对象,我喜欢这样。有一个UserRegisteredEvent 对象,一个OrderComplete 对象。我的问题是,类型本身是否绑定到事件处理程序?例如,我应该只将事件对象传递给publish方法吗?

EventManager.Publish(new UserRegisteredEvent(1));

这意味着每个处理程序都绑定到一个类类型,这似乎是有限的。虽然YAGNI可能是真的,但以下不是更强大:

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

事件主题就是处理程序绑定的内容。这样,处理程序可以从继承中受益。如果类型安全或使用无处不在的语言是一个问题,可以做:

EventManager.UserRegisteredEvent(1)

这只是较长发布版本的简短方法。这让我感到很恼火,因为这意味着必须为每个新事件改变类,这似乎是不必要的(如果使用上述方法,实际上也没有必要)。

虽然我只看到事件发布为没有主题的课程,但这是限制,还是有人遇到过这个问题?

2 个答案:

答案 0 :(得分:1)

域事件实际上并不需要特定的实现。毕竟它们只是语义DTO。我不明白你想要完成什么,但除非你正在构建一个服务总线,否则你只需发送事件对象即可由配置的任何处理程序处理。

事件不知道处理程序,处理程序彼此不了解,总线知道如何将事件发送给处理程序。并且您希望处理程序仅显式处理1个事件SRP。您可以将相关处理程序的实现组合到一个类中,但这是一个实现细节。

答案 1 :(得分:0)

如果您真的想介绍主题,我会通过界面继承来实现。例如:

interface IUserEvent : INonTransactionalEvent { ... }

class UserRegisteredEvent implements IUserEvent {
    public Timestamp: TTimestamp;
}

您的代码和语言的影响可以忽略不计,您可以继续使用接受Publish的通用INonTransactionalEvent方法,也可以轻松地重构您的主题。