事件采购和总聚合封装

时间:2017-03-06 14:23:06

标签: domain-driven-design cqrs event-sourcing

我发现Event Sourcing假设完全封装。聚合器允许访问其内部状态。国家内部保留只是强加有效的转换。据我所知,这个聚合(就外部世界而言)只是发出事件。而且我无法理解我的想法。我精炼我的模型以反映我的业务需求,这导致发布一些API的对象。例如,我有两个聚合根:购物车和订单。我想使用购物车中的ActiveItems来构建我的订单:

$order->addItems($cart->getActvieItems)

但这违反了关于聚合状态的完全封装的ES假设。如何根据ES良好实践使用ActiveItmes实现订单?我应该使用阅读模型吗?我认为这会导致知识泄漏模型(聚合)。提前谢谢!

3 个答案:

答案 0 :(得分:4)

Alexey说得对,事件采购只是一种持久性机制。我认为在考虑聚合时会产生混淆。在考虑聚合时,封装是一个重要的概念。这里的含义是它们不用于查询或UI。因此,CQRS非常适合。

但大多数应用程序需要查询数据或在UI上显示内容。这就是Read Models派上用场的地方。假设您正在使用CQRS和事件源(使用聚合时不需要),这是一件相当容易的事情。我们的想法是订阅事件并随时更新读取模型。这不会“泄漏”任何东西,因为功能在Aggregate域对象中。

为什么这是好事?

  1. 没有或非常有限的依赖关系使聚合更容易使用。
  2. 读取模型可以高度优化,因此可以非常快速地进行读取。
  3. 读取模型不需要复杂的查询和连接。
  4. 关注点明显分开
  5. 这种方法提供了巨大的扩展潜力
  6. 很容易测试
  7. 我相信还有更多。如果有帮助,我会在博客文章中概述典型的CQRS和ES架构。你会发现它很有用。您可以在此处找到它:CQRS + Event Sourcing – A Step by Step Overview

答案 1 :(得分:1)

除了将对象的状态保存为一系列事件之外,事件源不会假设任何事情。在进行事件采购时甚至没有要求“聚合”的要求。

如果您正在谈论DDD术语聚合聚合根,再次,事件采购只是一种将对象保存为事件流而不是最后的实际状态。没有额外强加的“要求”,如“完全封装”和内部状态的不可访问性。当然聚合(和其他对象)具有状态。

可能令人困惑的是,如果您还使用CQRS,则可以使您的聚合状态不被使用,因为其所有数据都是读取模型的瞬态数据。但这是别的东西,不需要盲目应用。

同样,事件采购只是一种持久性方法,仅此而已,而且不会少。

答案 2 :(得分:1)

  

$命令 - >为addItems($ cart-> getActvieItems)

除了在答案中全面介绍CQRS之外,我还想指出,在消息驱动系统中,命令(消息)应该是自包含的,并且必须封装所有必要的信息才能执行操作。

在上面的示例中,Order聚合接收命令AddItems,其中Items Ids列表作为有效负载。 AddItems命令处理程序需要获取其他信息来处理命令指向问题。 AddItems命令没有足够的有效负载,因此CartOrder在语义上耦合。你可能希望避免这种情况。

消息传递推理是关键所在。这是一些抽象

class AddItems : Command
{
   List ItemIds {get; set;}
}
class Order
{
   void AddItems(AddItems command){}
}
相关问题