【问题标题】:Domain Events require class or a topic?领域事件需要课程还是主题?
【发布时间】:2014-08-13 08:11:28
【问题描述】:

领域事件应该根据事件类,还是类和主题来调度?

例如,我有以下事件:

class UserRegisteredEvent implements INonTransactionalEvent{
    public Timestamp: TTimestamp;
}

还有一个活动经理,

class EventManager {
   /** Omitted **/
}

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

EventManager.Publish(new UserRegisteredEvent(1));

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

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

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

EventManager.UserRegisteredEvent(1)

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

虽然我只看到事件被发布为没有主题的类,但这是否有限制,或者有人遇到过这个问题吗?

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • “你想要一个处理程序来显式地只处理 1 个事件,SRP” 谢谢,这很好。在 SRP 之后,主题不是必需的,继承可能违反了这一点。谢谢!
    【解决方案2】:

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

    interface IUserEvent : INonTransactionalEvent { ... }
    
    class UserRegisteredEvent implements IUserEvent {
        public Timestamp: TTimestamp;
    }
    

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

    【讨论】:

    • 非常感谢,我没有想到接口继承!不过,我觉得下面关于违反 SRP 的答案更接近地回答了这个问题。谢谢! :)
    猜你喜欢
    • 2021-12-23
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-14
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多