DDD在长时间运行的过程中关联聚合

问题描述

我正在一个项目中定义两个聚合:“项目”和“任务”。除其他属性外,该项目还具有点属性。这些点按用户定义的方式分配给任务。在用例中,用户为某些任务分配点,但是项目必须具有这些点。 我们目前对此建模如下:

  1. “ task.RequestPoints(points)”,此方法将创建具有属性points和taskId的聚合PointsAssignment,该方法在其构造函数中发出PointsAssignmentRequested域事件。
  2. 发出事件的处理程序将获取与任务和聚合的PointAssigment相关的项目,并调用方法“ project.assignPoints(pointsAssigment,service)”,即,它将PointAssignment聚合作为参数和服务传递计算任务当前点与期望点之间的差。 如果可以使用点,则项目将修改其点属性,并发出“ ProjectPointsAssigned”域事件,该事件将包含pointsAssignmentId属性(以及其他属性
  3. 最后一个事件的处理程序将获取PointsAssingment并确认“ pointsAssigment.Confirm()”,此聚合将发出一个PointsAssigmentConfirmed域事件
  4. 最后一个事件的处理程序将调出关联的任务并调用“ task.AssignPoints(pointsAssignment.points)”

我的问题是:在步骤2中将聚合的PointsAssignment传递给项目方法是否正确?那是我发现能够关联聚合的唯一方法。 注意:我们已经创建了PointsAssignment聚合,以便在失败的情况下可以保存错误“ pointsAssignment.Reject(reasonText)”并将其显示用户,因为我使用的是最终一致性(每个事务1个聚合)。

我们考虑使用流程管理器(PointsAssingmentProcess),但是以同样的方式,我们需要第三项汇总的PointAssingment来关联此流程。

解决方法

我会做一些不同的事情(这并不意味着更正确)。 您的项目不需要了解有关PointsAssignment的任何信息。

如果您的项目是可以使用的点,则可以使用简单的方法来删除或添加点。

  • RemovePointsCommand->项目-> removePoints(点)
  • AddPointsCommand->项目-> addPoints(点)

然后,您将拥有一个事件处理程序,该事件处理程序将对PointsAssignmentRequested做出反应(我想这个家伙有项目的ID,点数以及您所说内容中的状态字段)

此eventHandler仅能做:

on(PointsAssignmentRequested)->调度命令(RemovePointsCommand)

//请注意,在此明智的做法是,客户端为该操作发送一个ID,因此它可以异步执行。

该命令可以成功或失败,并且它们都可以调度事件:

  • RemovePointsSucceed
  • 删除积分失败 // //请记住,您有一个先前保留的关联ID

然后,您将有一个最终的eventHandler可以做到:

  1. on(RemovePointsSucceeded)-> PointsAssignment.succeed()// 派遣PointsAssignmentSuccessed

  2. on(PointsAssignmentSuceeded)-> task.AssignPoints (pointsAssignment.points)

在失败方面

  1. on(RemovePointsFailed)-> PointsAssignment.fail()//调度PointsAssignmentFailed

通过这种方式,您不必将聚合混合在一起,他们所知道的都是彼此的id,并且它们可以在不了解其他聚合模式的情况下工作,从而避免了不必要的耦合。

我完全按照银行转帐的方式看到此问题的语义。

您拥有银行帐户(项目) 您的银行帐户中有钱(点) 您正在通过转帐流程(pointsAssignment)进行转帐 您正在将钱转入帐户(任务)

银行帐户的提款和入金操作最少,不需要了解转账过程。

转帐过程需要知道要从哪个银行提款以及要向哪个帐户存款。

我想象你的PointsAssignment就像

{
  "projectId":"X","taskId":"Y","points" : 10,"status" : ["issued","succeeded","failed"]
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...