gpt4 book ai didi

domain-driven-design - 聚合根工厂方法可以返回命令而不是发布事件吗?

转载 作者:行者123 更新时间:2023-12-01 13:38:56 41 4
gpt4 key购买 nike

在 Vaughn Vernon 的 Implementing Domain-Driven Design书中,他描述了在聚合根中使用工厂方法。一个例子是 Forum具有 startDiscussion 的聚合根返回 Discussion 的工厂方法聚合根。

public class Forum extends Entity  {

...

public Discussion startDiscussion(
DiscussionId aDiscussionId, Author anAuthor, String aSubject) {

if (this.isClosed()) {
throw new IllegalStateException("Forum is closed.");
}

Discussion discussion = new Discussion(
this.tenant(), this.forumId(), aDiscussionId, anAuthor, aSubject);

DomainEventPublisher.instance().publish(new DiscussionStarted(...));

return discussion;
}

如何在事件溯源系统中实现这种工厂模式,特别是在 Axon 中?

我通常相信 ,可以这样实现:
StartDiscussionCommand -> DiscussionStartedEvent -> CreateDiscussionCommand -> DiscussionCreatedEvent
我们解雇了 StartDiscussionCommandForum处理, Forum然后发布 DiscussionStartedEvent .外部事件处理程序将捕获 DiscussionStartedEvent ,转换它,然后触发 CreateDiscussionCommand .另一个处理程序将实例化 Discussion使用 CreateDiscussionCommandDiscussion会触发 DiscussionCreatedEvent .

或者 ,我们可以改为: StartDiscussionCommand -> CreateDiscussionCommand -> DiscussionCreatedEvent
我们开火 StartDiscussionCommand ,这将触发命令处理程序并调用 Forum的 startDiscussion() 方法将返回 CreateDiscussionCommand .然后处理程序将调度这个 CreateDiscussionCommand .另一个处理程序接收命令并使用它来实例化 Discussion . Discussion然后会触发 DiscussionCreatedEvent .

第一种做法涉及 4 个 DTO,而第二种做法仅涉及 3 个 DTO。

关于应该首选哪种做法的任何想法?还是有其他方法可以做到这一点?

最佳答案

解决此类问题的最佳方法是首先将您的聚合(实际上是整个系统)视为黑匣子。只需查看 API。

Given a Forum (that is not closed),
When I send a StartedDiscussionCommand for that forum,
A new Discussion is started.

但是也
Given a Forum that was closed
When I send a CreateDiscussionCommand for that forum,
An exception is raised

请注意,您建议的 API 技术性太强。在“现实生活”中,您不创建讨论,而是开始讨论。

这意味着论坛的状态与讨论的创建有关。所以理想情况下(当查看黑匣子时),这样的场景将在论坛聚合中实现,并应用一个代表讨论聚合的创建事件的事件。这是假设其他因素要求论坛和讨论是两个不同的集合。

因此,您实际上并不希望 Command 处理程序返回/发送命令,而是希望该处理程序决定是否创建聚合。

不幸的是,Axon 还不支持此功能。目前,Axon 无法通过其常规 API 应用属于另一个聚合的事件。

但是,有一种方法可以完成它。在 Axon 3 中,您不必 apply一个事件,您也可以直接将一个事件发布到事件总线(在事件源的情况下,这将是一个事件存储实现)。因此,要实现这一点,您可以直接发布包含 DiscussionCreatedEvent 的 DomainEventMessage。讨论的ID可以是任何UUID,事件的序号为0,因为它是讨论的创建事件。

关于domain-driven-design - 聚合根工厂方法可以返回命令而不是发布事件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41971722/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com