0

举这个例子。主管域类公开了一个方法 GetUnderlings (DateTime from, DateTime to),它将返回在给定时间段内由给定主管监督的所有人员。

出于令人愉悦的语义原因,该方法应该放在此处。但是应该去其他地方以获得 DDD 纯度。那是因为我假设实现需要使用存储库的方法,将其嵌入域实体中似乎是错误的。在这种情况下,该方法应该在 Respository 或 Service 上运行 - GetUnderlings(Supervisor supervisor, DateTime from, DateTime to)

其他人如何处理这种情况?

编辑:我认为这些力量可以这样描述:根据 OO 原则,我希望我的实体的公共接口能够公开一组丰富的面向业务的功能。但是根据 DDD 实现原则,这些方法的实现可能最好位于其他地方。例如,在服务中。

这种明显的冲突如何解决?我能看到的方法是:

  1. 让实体具有对服务或服务接口的引用
  2. 始终让客户端访问服务,而不是直接访问实体(结果:失去一致性,从 OO 的角度来看完全不酷)
  3. 使用“领域事件”(?)
  4. 使用一些 AOP 技巧将方法的实现委托给服务。
4

3 回答 3

2

如果Supervisor是一个它是有效的,从但只是READONLY集合Aggregate Root返回Underlings列表是有效的,因为应该被修改以将域规则和不变量应用于修改操作。(基本规则不仅在 DDD 中,也是很好的 OOP 设计)SupervisorUnderlingsSupervisor

Underlings好像是一段历史entity。在大多数情况下(我没有足够的上下文信息来确认您的情况)历史entities没有aggregate roots并且只有 aggregate roots存储库。

请记住,如果检索的Undelings是 for UI(不应用具有规则和不变量的操作),您不需要关心aggregate roots,entities等,因为您应该应用 CQRS 并使用视图服务来检索纯数据(第一范式, not aggregate roots) 将其展示给用户。当用户触发操作时,UI您需要检查规则(即应用 DDD);Supervisor您从中检索Repository,检查Underlings(记住,只读集合)以做出决定,应用操作并保存更改。

于 2013-10-18T12:04:44.383 回答
0

一种常见的方法Supervisor是将 all 公开Underlings为只读集合。如果您需要实现按日期范围过滤它们的方法,您只需将此方法添加到类SupervisorGetUnderlings(DateTime from, DateTime to),一切正常。

如果通用方法不起作用,因为您Supervisor有很多Underlings,或者检索所有这些很耗时Underlings,或者......有一个解决方法 - Martin Fowler 的“分离接口”(PoEAA)模式。

您可以Underlings在域模型中定义在特定日期范围内返回的组件接口,但在另一层(例如数据访问层)中实现它。

在这种情况下,您的域实体没有对服务的引用,也没有公开任何“下属”。所有需要获取“Underlings”调用服务并将“Supervisor”实例传递到方法和日期范围的客户端。

在此处输入图像描述

于 2013-10-18T21:02:06.240 回答
0

如果它们属于 Supervisor 聚合,Supervisor 应该有一个 Underlying 的集合。

喜欢

class Supervisor {
    private Collection<Underlying> underlyings;
}

然后 GetUnderlings(DateTime from, DateTime to) 正在过滤底层。这可以。

但是如果有太多的底层属于一个主管,这个解决方案对性能是不友好的。在这种情况下,我想使用 make Underlying 聚合根并使用它的 Repository 来检索结果,例如:

interface UnderlyingRepository {
      Collection<Underlying> GetUnderlings(Guid supervisorId, DateTime from, DateTime to);
}

客户端(可能是 MVC 控制器)直接调用存储库。那么问题是如何保护 addUnderlying 的不变量,这些不变量曾经受到 Supervisor 聚合的保护。您可以使用 DomainService 或 DomainEvents。

上面的解决方案是基于传统的 DDD 架构模型。就像@jlvaquero 所说,您可以改用 CQRS。

于 2013-10-19T00:59:52.873 回答