DDD通用领域事件与特定领域事件的区别

6
我是一名有用的助手,可以翻译文本。
我正在研究域事件,具体包括以下两种可能性:
A. 使用“通用”事件,如下所示:
public class OrderStateChangedEvent : IEvent
{
  public Guid OrderId { get; }
  public OrderState NewState { get; }
}

然后消费者将确定新状态并执行某些操作。由于我使用Rx,这不会很难(而且比使用switch / case语句要好得多):

var subscription = DomainEvents
     .AsObservable<OrderStateChangedEvent>()
     .Where(e => e.NewState == OrderState.OrderCompleted)
     .Subscribe(OnOrderCompleted);

B. 使用特定事件:

public class OrderCompletedEvent : IEvent
{
  public Guid OrderId { get; }
}

这会导致更多的事件类,一方面可能太多,另一方面事件类名包含语言,这可能是一个优点。

你有什么建议吗?我对领域事件不熟悉,在这里不能做出合格的决定(两者似乎都没有任何主要缺点)

2个回答

2
这将归结于“通用”事件是否导致任何行为。如果它仅作为类别之类的有趣值,则通用事件就足够了。
但是,如果事件附带任何特定行为,并且因此在系统中具有任何特定含义,我肯定建议采用更明确的方法。

实际上,特定事件会附带行为。对于通用事件,订阅者将尝试自行确定行为,因此选择特定事件更有意义 - 尽管某些任务(例如“订阅特定域对象的所有状态机更改”)可能更难完成,因为这些状态更改意味着不同的事情(订单完成,订单取消,订单履行开始等)。 - Lev
1
当你只是在进行数据挖掘时,订阅多个事件肯定会更加繁琐。然而,在这种情况下,还有其他技术可以实现。你可以发布一个特定的和一个通用的事件。如果使用事件溯源,事件处理器可以从事件流中获取相关事件,并使用共享处理方法进行处理。像往常一样,我们需要在实践中考虑这些事情 :) - Eben Roux
我刚刚发现我可以使用逆变订阅,所以我只需要用一个接口标记我感兴趣的事件即可。 - Lev

1
作为一个经验法则,使用switch语句在面向对象的编程语言中通常被认为是代码异味。

http://c2.com/cgi/wiki?SwitchStatementsSmell

如果我理解正确,B更加明确,同时使代码更加简洁:
var subscription = DomainEvents
   .AsObservable<OrderCompletedEvent>()
   .Subscribe(OnOrderCompleted);

我不会在两种变体中使用switch case,正如所述。 - Lev
我认为在类型字段上使用“where”选择子句是一种“switch”。 - Alexander Langer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接