我刚刚进入事件驱动架构,想知道命名命令和事件的约定是什么。我知道很多:命令应该采用 DoSomething 的形式,而事件应该采用SomethingHappened 的形式。我需要澄清的是,如果我需要将“命令”一词附加到我的命令中,并将“事件”附加到我的事件中,例如 DoSomethingCommand 而不是 DoSomething 和SomethingHappenedEvent 而不是只是SomethingHappened。我还想知道社区首选公约背后的基本原理是什么。谢谢!
5 回答
Command
和后缀是可选的Event
并且是一个偏好问题。我更喜欢省略它们,并尝试仅从名称中使意图明显。命名命令和事件的最重要方面是确保它们更多地反映业务领域而不是技术领域。很多时候,诸如创建、更新、添加、更改之类的术语过于技术化,在业务领域中意义不大。例如,UpdateCustomerAddress
您可以说RelocateCustomer
哪个可能有更大的业务背景,而不是说。
我的约定取决于命名空间,我的意思是我从不使用后缀事件或命令。
我还根据它们要影响的聚合类型将命令和事件组织到单独的命名空间中。
例子:
// Commands
MyApp.Messages.Commands.Customers.Create
MyApp.Messages.Commands.Orders.Create
MyApp.Messages.Commands.Orders.AddProduct
// Events
MyApp.Messages.Events.Customers.Created
MyApp.Messages.Events.Orders.Created
MyApp.Messages.Events.Orders.ProductAdded
根据您的要求,您可能希望将事件放入单独的程序集中。这样做的原因是如果您需要将事件分发到下游系统。在这种情况下,您可能不希望下游系统不得不为您的命令而烦恼(因为它们不应该)。
我经常看到并使用自己的约定是事件应该是过去时并描述发生的事情:
- 用户注册
- 帐户激活
- 回复已发布
命令是你想做的事情。因此,请创建说明以下内容的名称:
- 创建用户
- 升级用户帐户
至于组织,我通常将它们与它们所针对的根聚合放在一起。它使您可以更轻松地查看您可以做什么以及生成了哪些类型的事件。
也就是说,我为每个根聚合创建一个命名空间,并将所有内容(存储库定义、事件、命令)放在其下。
- MyApp.Core.Users
- MyApp.Core.Posts
等等
如果您的命令/事件被正确命名,附加命令和事件将是多余的信息。这将是使您的代码可读性降低的噪音。还记得匈牙利符号吗?大多数程序员(据我所知)不再使用它。
命令和事件为您的应用程序形成一种语言……一种 API。使用诸如“命令”和“事件”之类的术语可能对系统级定义有用,其中技术术语有意义地混合到实体的目的中,但如果您正在处理域行为的定义,则删除系统/技术术语并青睐商务人士。它将使您的代码更自然地阅读并减少打字。我从“命令”/“事件”附件开始,但意识到这是浪费时间,并把我从 DDD 普及的无处不在的语言中拉了出来。HTH,迈克