首页 > 解决方案 > CQRS 中的命令和事件类之间共享的命令模型类

问题描述

在我当前使用 EventSourcing 和 CQRS 和 Java 的 Monolithic 应用程序中,我们有一个单独的写入和读取模型。

package com.command;
class Address{ //class created in Command Write model
   String address;
} 

package com.command;
import com.command.Address;
class CreateEmployeeCommand { //Command class belongs to Write Model
  Address address; //this is correct
}


package com.events;
import com.command.Address;
class EmployeeCreatedEvent { //Event class belongs to Read Model
 Address address; //this should not be correct IMO, instead seperate Address class should be created in event package.
}

在上述命令和事件类中,命令模型类“地址”已在它们之间共享。我认为上面是不正确的,而是应该为每个读写模型创建单独的地址类。通过使用上述方法,我们是否违反了关注点分离原则?以及如果我们在 Command 和 Event 类之间共享相同的 Command 模型,我们真正面临的其他实际问题是什么。请让我知道我的想法是对还是错..

标签: microservicescqrsevent-sourcingevent-drivenevent-driven-design

解决方案


我认为你在这里不合时宜。

CreateEmployee并且EmployeeCreated在消息的内存表示中;这些消息是 API 表面的一部分。如果您的CreateEmployee 架构EmployeeCreated 架构对 的理解相同Address,那么如果您也共享相同的数据结构,那么您就不太可能遇到问题。

换句话说,您考虑应用的相同约束Address也适用于更简单的事物,例如CustomerId; 是的,您的模型中可以有多个表示CustomerId,但是您从中获得了什么优势?


在某些地方,同一广泛概念的多种表示可能有意义:例如 UnverifiedAddress 和 VerifiedAddress 是两个不同的东西。

在某些情况下,消息的消费者使用与生产者不同的内存表示是有意义的——您的读取模型可能使用与写入模型不同的内存表示。同样,不同的消费者对同一想法有不同的记忆表示可能是有意义的。

最简单的版本是当您处理以不同语言实现的消费者时。当您使用单体时不太可能出现。


推荐阅读