DDD存储库输入参数

时间:2016-08-25 10:50:37

标签: domain-driven-design ddd-repositories

在以下示例中,建议使用哪种方法来实现_customRoleRepository? 以下代码在应用程序服务中执行。

var user = _userRepository.GetById(1);
var customRole = _customRoleRepository.GetById(user.CustomRoleId);

var user = _userRepository.GetById(1);
var customRole = _customRoleRepository.GetForUser(user);

3 个答案:

答案 0 :(得分:1)

考虑到两个选项,我可能会选择第一个选项,这样可以保持ID访问的一致性。

如果可能,最好在加载用户时加载自定义角色,以避免再次往返数据库,特别是如果这是常见操作。这可以作为阅读模型实现。

这假设您已正确建模聚合...:)

答案 1 :(得分:1)

两者都同样有效,具体取决于您的需求。如果您想在尝试检索角色之前确保调用代码具有有效的User聚合,那么GetForUser会很好 - 如果您想要调用代码,它会将customRoleRepository与User聚合的知识结合起来要有一个有效的用户聚合,那么该耦合就有目的。

GetByUserIdGetById更加一致且耦合程度更低,因此如果在您的上下文中即使客户没有调用GetByUserId也无关紧要有一个有效的用户聚合,那也没关系。

如果您正在加载ById,我也发现使用类型化身份值对象可以非常有助于提供额外级别的类型安全 - 有关这里的优缺点的一些对话https://stackoverflow.com/a/5377460/6720449和此处{{ 3}}

答案 2 :(得分:0)

讨厌说,但在DDD环境中,我的答案都不是。

在您的第一个示例中,角色存储库可能不知道用户域是否合适,但这意味着应用程序需要知道要获取从用户提取id然后查询另一个存储库所需的角色。换句话说,应用程序充当用户和角色之间的映射器。

在第二个示例中,角色存储库现在需要了解用户域。不是很好,但另一方面,应用程序不再需要了解roleId。这很好。经典的两种方法之间的权衡。

但在这两种情况下,应用程序仍然需要两个存储库来获取它的信息。当需要更多关系时会发生什么?存储库的数量可以快速增长,事情变得一团糟。

在域驱动设计中,您应该尝试根据聚合根(AR)和域上下文进行思考。对于您的示例上下文,用户是AR,角色将成为子级。所以你可能有:

var user = _userFinder.GetById(1);
var customRole = user.CustomRole;

隐藏了应用程序中的大部分实现细节,并允许您关注域实体实际需要执行的操作。