Domain driven design DDD存储库输入参数

Domain driven design DDD存储库输入参数,domain-driven-design,ddd-repositories,Domain Driven Design,Ddd Repositories,在以下示例中,建议采用哪种方式实现\u customrolereposition? 以下代码在应用程序服务中执行 var user = _userRepository.GetById(1); var customRole = _customRoleRepository.GetById(user.CustomRoleId); 或 我不想这么说,但在DDD环境中,我的答案是两者都不是 在第一个示例中,角色存储库可能不知道用户域,这很好,但这意味着应用程序需要知道,要获得角色,它需要从用户中提取一个

在以下示例中,建议采用哪种方式实现
\u customrolereposition
? 以下代码在应用程序服务中执行

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


我不想这么说,但在DDD环境中,我的答案是两者都不是

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

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

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

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

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

这对应用程序隐藏了大部分实现细节,并允许您关注域实体实际需要做什么。

我不想这么说,但在DDD环境中,我的答案是两者都不是

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

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

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

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

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

这对应用程序隐藏了大部分实现细节,并允许您专注于域实体实际需要做的事情。

鉴于这两个选项,我可能会选择第一个选项,它保持了通过ID访问的一致性

如果可能,最好在加载用户时加载自定义角色,以避免再次往返数据库,尤其是在这是一个常见操作的情况下。这可以实现为一个读取模型


这是假设您已经正确地建模了聚合…:)

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

如果可能,最好在加载用户时加载自定义角色,以避免再次往返数据库,尤其是在这是一个常见操作的情况下。这可以实现为一个读取模型


这是假设您已经正确地建模了聚合…:)

根据您的需要,两者都同样有效<如果您想在尝试检索角色之前确保调用代码具有有效的用户聚合,那么code>GetForUser将是一个不错的选择—虽然它确实将customRoleRepository与用户聚合的知识相耦合,但如果您想要求调用代码具有有效的用户聚合,那么这种耦合是有目的的

GetByUserId
GetById
更为一致,耦合更少,因此,如果在您的上下文中,即使客户端没有有效的用户聚合,调用
GetByUserId
也没关系,那么也可以


如果您正在加载ById,我还发现使用类型化的identity valueobjects在提供额外的类型安全性方面非常有帮助-根据您的需要,关于此处和此处的利弊的一些对话同样有效<如果您想在尝试检索角色之前确保调用代码具有有效的用户聚合,那么code>GetForUser将是一个不错的选择—虽然它确实将customRoleRepository与用户聚合的知识相耦合,但如果您想要求调用代码具有有效的用户聚合,那么这种耦合是有目的的

GetByUserId
GetById
更为一致,耦合更少,因此,如果在您的上下文中,即使客户端没有有效的用户聚合,调用
GetByUserId
也没关系,那么也可以


如果您正在加载ById,我还发现使用类型化的identity valueobjects在提供额外的类型安全性方面非常有帮助—这里和这里关于优缺点的一些对话

CustomRole代表BC中的另一个AggregateRoot。它有自己的实体(权限)等。多组用户可以共享相同的自定义角色。您的建议是将CustomRole视为一个值对象,当CustomRole更新时,我必须将该更改传播给该角色中的所有用户?同一bc中的两个AR听起来很麻烦。在您的示例中,我将考虑角色是一个值对象。我会有一个不同的bc来更新角色,然后发送通知告诉用户角色已更改。当然,这在很大程度上取决于您是否真的需要处理复杂的业务逻辑。在不了解全局的情况下,很难提出具体的建议。顺便说一句,我认为这类问题会得到更好的回答。我不会走那么远,说同一个BC中的Agroots听起来很麻烦。沃恩·弗农在他的演讲中