微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我应该将哪些数据保留在聚合中

如何解决我应该将哪些数据保留在聚合中

我正在学习 CQRS 和事件溯源架构 (with nestjs),我对聚合有点困惑。

我遵循此处解释的架构类型:https://danielwhittaker.me/2020/02/20/cqrs-step-step-guide-flow-typical-application/

如果我理解得很好,聚合根就是我的“写模型”。它使用将提交给事件总线的事件更新自身,我使用事件历史记录(或缓存)获取其当前状态。

因为我从来没有真正读取聚合根中的数据(只有接受或不接受下一个命令所需的数据),而且我不坚持它(事件是),如果我真的需要保留我的所有数据汇总?

我不确定我是否清楚,所以让我们看一个简化的例子:

我有一个用于购物网站的 CreateProduct 命令和一个 ProductCreated 事件。我使用事件的内容为某些查询创建视图,例如 GetProductByCategorySearchProduct、...

这里的命令:

class CreateProduct {
  public name: string;
  public description?: string;
  // ...
}

我跳过了 commandHandler。如果我理解得很好,我的聚合根应该是这样的:

class ProductAggregateRoot extends AggregateRoot {
   public id: string;
   private name: string;
   private description?: string;
   
   create(data: { name: string,description?: string }) {
     if (! data.name) {
        throw Error('Name is required');
     }
     this.apply(new ProductCreated(uuid(),data));
   }
   
   onProductCreated(event: ProductCreated) {
     this.id = event.id;
     this.name = event.name;
     this.description = event.description;
   }
}

我可以吗:

class ProductAggregateRoot extends AggregateRoot {
   public id: string
   
   create(data: { name: string,data));
   }
   
   onProductCreated(event: ProductCreated) {
     this.id = event.id;
   }
}

因为我从不在命令端使用 namedescription?在查询端创建视图对我来说很有用。

这让我很困惑,因为它似乎离域很远(产品不仅仅是一个 id)。但我不明白将这些数据保留在这里的意义。如果我改变主意,我可以稍后添加它并从历史中重建我的聚合根。

解决方法

我不特别了解 nestjs,但在事件溯源应用程序的一般实现中,绝对可以只让我们满足您的业务规则所需的字段。因此,在这种情况下,由于没有涉及名称或描述的规则,因此在您处理其他命令(可能是 DeleteProduct 或类似命令)时,它们不需要具体化到聚合根类中。

当您应用下一个命令时,您的应用程序应该再次从事件历史中具体化聚合根,因此您可以稍后根据需要添加字段。

您可以在此处 (https://serialized.io/java/working-with-aggregates/) 中看到来自序列化 Java 客户端的示例,其中 OrderPlaced 事件包含一个 amount,在处理命令时不会将其读入 Order 聚合的瞬态状态.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。