在命令和事件中使用值对象?

Ash*_*ari 2 domain-driven-design cqrs event-sourcing axon

我们可以在命令中使用值对象吗?

假设我有一个商店(聚合),其中有一个值对象地址。在值对象构造函数 Address 中,我放置了一些地址验证逻辑。因此,如果我在 command (CreateShopCmd) 中使用该 Address 对象,那么它会在制作 command 时得到验证,但我想要或读取的验证应该存在于命令处理程序中。

但问题是,我必须再次将验证放入命令处理程序中(因为验证已存在于地址构造函数中),如果我不将其放入命令处理程序中,那么当我在中创建地址对象时,将进行验证事件处理程序并分配给商店聚合(这是不正确的)

所以,请指导我。

下面是代码示例

   @Aggregate
   @AggregateRoot
   public class Shop {

   @AggregateIdentifier
   private ShopId shopId;
   private String shopName;
   private Address address;

   @CommandHandler
   public Shop(CreateShopCmd cmd){

     //Validation Logic here , if not using the Address in 
     // in cmd

         //Fire an event after validation
         ShopRegistredEvt shopRegistredEvt = new ShopRegistredEvt();
         AggregateLifecycle.apply(shopRegistredEvt);
     }

     @EventSourcingHandler
     public void on(ShopRegistredEvt evt) {

     this.shopName = evt.getShopName();

     //Validation happend here if not put in cmd at the time of making 
     //Address object - this is wrong
     this.address = new Address(evt.getCity(),evt.getCountry(),evt.getZipCode())

     }


   }

  public class CreateShopCmd{

    private String shopId;
    private String shopName;
    private String city;
    private String zipCode;
    private String country;

   }

 public ShopCreatedEvent{

    private String shopId;
    private String shopName;
    private String city;
    private String zipCode;
    private String country;

}
Run Code Online (Sandbox Code Playgroud)

All*_*ard 5

在命令或事件中使用值对象在概念上没有任何问题。但是,您应该谨慎使用它们。

消息的结构可能会随着时间而改变。如果您在消息中过度使用了值对象,那么值对象之一的更改如何改变不同消息的结构可能会变得不太清楚。

对于代表“通用”概念的值对象(例如地址),这并不是什么大问题。但一旦值对象变得更加特定于领域,这可能会成为一个问题。