DDD 集成:命令处理程序问题?



我使用的是DDD架构,我很难理解一些东西。

这是我项目的方案: 方案

首先,在提出问题之前,我会举一个例子,然后我会提出问题。

假设我们要管理工人为公司工作的小时数,我们有以下聚合:

时间跟踪(实体根目录(

  • 小时跟踪金ID
  • 公司编号
  • 工作人员编号
  • 入场时间
  • 退出时间

工作人员(实体(

  • 工作人员编号
  • 公司编号
  • 允许时间跟踪
  • 工人假期列表

公司(实体(

  • 公司编号
  • 允许时间跟踪
  • 公司假期列表

假日(值对象(

  • 假日身份证
  • 开始日期
  • 结束日期

从我们的 WPF 应用程序或 Web 服务(使用 和 应用程序或其他任何内容(中,我们使用命令发送公司 ID 和 workerID。

我的问题如下:

  1. 我收到一个只有工人ID和公司ID的命令,但我显然需要检索这些实体和时间跟踪ID的信息(如果工作人员没有和退出时间(。应该在哪里做?在通过存储库的命令处理程序中?或者命令应该已经包含所有信息?

  2. 假设我们在命令处理程序中拥有第一个点的信息,现在我们应该使用我们拥有的信息创建一个 TimeTracking 聚合根。然后根据数据,我们将调用 TimeTracking 实体的 DoExit((/DoEntry(( 函数。 谁应该负责添加/更新时间跟踪?函数是否应该验证业务规则,例如不在假期、允许跟踪等,并返回 true 或 false,然后命令处理程序执行添加/更新?或者函数应该创建一个执行进入/退出的域事件来委派添加/更新?

  3. 另一方面,我应该如何使用命令处理程序中可能的错误更新 UI?例如,公司不存在,应该以某种方式通知,因此在命令处理程序中返回具有成功/错误和错误类型的对象将是一个正确的解决方案? 在验证业务规则时也是如此,我是否也应该返回一个对象来传达错误? 因此,如果我们执行以下操作:调用 DoEntry(( 时,公司不允许跟踪,我将一个对象错误返回给命令处理程序,该处理程序也将返回此错误,是否正确?

  4. 最后,对于每个操作和实体的操作(编辑工人、删除时间跟踪......(,我们需要一个命令吗?

我认为你的设计是颠倒的。 我假设 WorkerID 只能与单个公司关联,而 HourTrackingID 只能与单个 Worker 关联。 通常,聚合根是"一对多"关系的"一"部分,这意味着 Worker 是 AR,而 TimeTracking 是一个聚合。

您的命令将是 ClockInWorker 并传递 WorkerID。 CompanyID 是不必要的,因为此命令不关心工作人员为谁工作,只关心他们打卡。 此命令将调用方法 Worker.DoEntry,该方法将创建具有输入时间的 TimeTracking 记录。 然后你有另一个命令ClockOutWorker 它以相同的方式工作,但调用Worker.DoExit。

数据验证(检查 worker ID 是否有效(在 API 和命令中同时进行。 假设 WorkerID 是一个 GUID,API 会验证它是否收到了实际的 GUID。 API 不会验证 guid 是否对应于真正的辅助角色 - 这取决于命令。 API 确保请求在语法上有效,命令确保遵循业务规则。

您不显示假期是否属于公司。 如果是这样,那么公司应该通过 Company.CanWorkerLogTime(workerID, logDate( 方法验证假期。 这应该在调用 Worker.DoItem 之前从命令中调用。 您可以从工作人员获取公司 ID。 如果假期不属于公司,那么您可以使用方法CanWorkerLogTime(logDate(制作HolidayService

最新更新