让我们以一个简单的“帐户注册”示例为例,流程如下:
- 用户访问网站
- 点击“注册”按钮并填写表格,点击“保存”按钮
- MVC控制器:通过读取ReadModel验证用户名的唯一性
- RegisterCommand:再次验证用户名唯一性(这是问题)
当然,我们可以通过读取MVC控制器中的ReadModel来验证UserName的唯一性,以提高性能和用户体验。但是,我们仍然需要再次在RegisterCommand中验证唯一性,并且显然,我们不应该在Commands中访问ReadModel。
如果我们不使用事件源,则可以查询域模型,所以没有问题。但是,如果使用事件源,则无法查询域模型,那么如何在RegisterCommand中验证用户名的唯一性?
注意: User类具有Id属性,而UserName不是User类的键属性。使用事件源时,我们只能通过Id获取域对象。
顺便说一句:在要求中,如果已使用输入的用户名,则网站应向访问者显示错误消息“对不起,用户名XXX不可用”。向访问者显示一条消息,例如:“我们正在创建您的帐户,请稍候,我们将稍后通过电子邮件将注册结果发送给您”,这是不可接受的。
有任何想法吗?非常感谢!
[更新]
一个更复杂的示例:
需求:
下订单时,系统应检查客户的订购历史记录,如果他是有价值的客户(如果客户在去年每月至少下达10个订单,那么他是有价值的),我们将为您减价10%。
实现方式:
我们创建PlaceOrderCommand,在命令中,我们需要查询订购历史记录以查看客户端是否有价值。但是,我们该怎么做呢?我们不应该在命令中访问ReadModel!正如Mikael所说,我们可以在帐户注册示例中使用补偿命令,但是如果在此订购示例中也使用补偿命令,它将太复杂,并且代码可能很难维护。