【发布时间】:2015-12-15 12:21:58
【问题描述】:
我有两个聚合。
Person {
private personID personID;
private nodeID nodeID; //belongs to node
}
Node {
private nodeID nodeID; //node's id
private nodeID parent; //parent node reference by id
public void assign(Person person);
}
现在我为我的人分配服务有了域逻辑:
可以将人员分配给节点"X",前提是他属于节点"Y",该节点是节点"X" 的父级或曾祖父或曾曾祖父或...。
要找出答案,我需要查询Read Model。
我在域中,所以我不能只使用我的读取模型来查询它。
我认为我不能只添加到我的存储库,连接到读取模型,因为它连接到我的事件存储。特别是当Read Model可以放在另一个服务器上,成为另一个应用程序。
实现它的正确方法是什么?
【问题讨论】:
-
读取模型只是一个抽象,你可以在你的领域中使用它。 CQRS 是关于如何对业务用例建模的设计原则,它不是将 2 个桶分开的规则。事实上,CQRS 应用于有界上下文,因为模型的某些部分用于更改业务状态(命令),而其他部分不更改任何内容(查询)
-
好吧。我理解,读取和写入在同一个有界上下文中。但问题在于技术层面。我不能只查询读取模型并在那里查找我的聚合,因为聚合之类的东西在那边不存在。读取模型包含非规范化数据,因此我将无法从中构建事件源聚合。什么负责查询读取模型、存储库?还是某种抽象,实际上会向读取模型的 REST API 发送请求?
-
您不使用 RM 来查询聚合,只是为了获取业务决策所需的数据。我的观点是,你的聚合试图做太多事情,你应该仅使用它来改变概念状态,而不是用于与概念相关的所有事情。对于业务查询,您拥有根据业务规则解释现有状态(读取模型)的域服务。聚合的目的只是强制执行保持概念有效/一致的业务约束,所有其他行为都属于域服务。
-
那么以这种方式实现它是完全没问题的吗? PersonAssigningService -> 将保护与聚合本身无关的分配不变量,并将使用 PersonAllowedToAssignToNodeStrategy (不能有更好的名称 atm :)),策略将是接口。此策略的实施将查询 RM Rest API 以获取必要的信息。
-
我的意思是你应该在那个服务器上也有一个读取模型,用于本地查询。因此,您的“命令”服务器上有一个(也许更具体,定制的)RM,而“查询”服务器上有另一个。是的,这意味着 RM 重复(实际上,只需在两台服务器上使用相同的库),但这也意味着您的服务器没有耦合并且性能不会受到影响。称之为权衡。
标签: java c# domain-driven-design cqrs event-sourcing