在我的公司,我们目前使用DDD架构,结合事件采购和CQRS。在初始版本中,我们允许每个上下文从任何其他上下文接收事件。然而,这很快变得一团糟,因为很难跟踪哪些事件被处理在哪里。
我们当前的方法是仅允许将命令发送到其他上下文。这样做效果更好,但似乎会产生大量的代码开销。例如:
context A sends a command to context B,
which changes the state of a domain model,
which publishes an event,
which gets handled by an event handler,
which sends a command back to context A,
which changes the state of a domain model,
which publishes an event,
which gets handled by an event handler,
which sends a command to context C,
etcetera.
许多不同上下文中的域模型以及触发发送到另一个上下文的命令的很多事件都包含许多类似的数据。特别是在我们的客户网站上下文中,模型几乎不包含逻辑或状态,仅用于生成可以对网站数据库进行非规范化的事件。虽然发布事件不应该是任何领域模型的唯一目的,但它似乎仍然没有办法实现。
我们现在的一个想法是让我们的CMS充当领域模型,直接处理命令,而不是通过模型发送它们并处理结果事件。这是处理这些案件的正确方法吗?还有其他更有效的方法在上下文之间进行通信吗?
答案 0 :(得分:2)
在初始版本中,我们允许每个上下文接收事件 来自任何其他背景。然而这很快变得一团糟,因为它 变得非常难以追踪哪些事件被处理在哪里。
我没有看到这个问题。通过事件在BC之间进行通信是典型的事件驱动架构。可以使用上下文映射来跟踪事件。
然而,在你的情况下,BC的互动似乎变得过于繁琐。这可能是次优边界的症状。也许边界过于细化?鉴于几个域模型包含许多类似的数据,可能表明这些域应该合并。 BC的基本原则是功能性和语言性cohesion - 与密切相关的事物粘在一起。
响应命令后发布事件的域模型更改状态是完全有效的工作流。
特别是在我们的客户网站上下文中,模型几乎包含 没有逻辑或状态,只是用来生成可以的事件 非规范化到网站数据库。
这似乎就像CQRS术语中的观点/预测一样。再说一遍,没错。
我们现在的一个想法是让我们的CMS充当领域模型,并且 直接处理命令而不是通过模型发送它们 处理由此产生的事件。
这可能是一个重要的观察。在业务逻辑复杂的情况下,完全成熟的域模型才有意义。但是,如果域是CMS或CRUD的域,则不需要域模型。但是,您仍然可以保留事件驱动架构的其余部分。