如何在DDD中命名和实现结果集行?

时间:2017-09-17 20:11:28

标签: php pdo domain-driven-design ddd-repositories

在DDD中,您有一个具有唯一标识符(ID或UUID)的实体。通常,实体表示数据库表中的可存储行。我的存储库可以一次加载单个实体(findById)或所有实体(findAll)。

但现在必须编写一个特殊且非常复杂的查询,并将其连接到其他表。结果集不再是特殊的(用户)实体,因为我从具有别名的多个表中选择了不同的字段,依此类推。根据查询,结果可能不包含id。

我已成功地将这些行水合成一个新的对象集合,但却对该事物的名称(和类型)感到挣扎。

我的问题是:

如何命名和分类来自DDD中自定义查询的此类行?

2 个答案:

答案 0 :(得分:2)

首先,除非您真正使用特定聚合,否则应避免查询域模型。即便如此,根据您的设计,您可能无法获得所需的数据。

典型的建议是使用专门的查询层以及可能代表所需数据的读取模型。该读取模型可以根据需要键入或松散。例如,如果一个名称/值对列表可以执行这个技巧,您可以选择那个

这些查询实际上并不是域的一部分,因此在建模方面不属于域驱动设计。然而,它们作为整体架构/方法的一部分非常重要。

<强>更新

回应@Luca Masera的评论:

我通常会使用类似这样的内容(C#),例如Product

public interface IProductQuery
{
    int ActiveCount();
    DataRow Details(Guid id);
    Query.Product Get(Guid id);
    IEnumerable<Query.Product> Matching(ProductSpecification specification);
}

Query命名空间是为了让阅读模型Product不会干扰我的实际域Product

根据我的要求,我将使用适当的返回对象/结构/类型。

答案 1 :(得分:2)

这里似乎需要一个查询服务。

DDD非常适合CQRS,我相信你想要的结果是只读的。

在这种情况下,您可以根据需要创建一个特殊对象:UserData,如果用户包含某些其他关系(如角色集合),或者权利,您可以将其称为UserRightsData,并从UserQueryService获取它。

查询服务通常位于应用程序层中。

如果您想要非只读结果,而不是您可以操作和保留的纯实体,那么您需要提供更多详细信息。特别是,您应该能够通过应用程序服务从存储库加载此实体,调用域操作并将其保留。

查询服务非常适合视图,表格和数据显示,具有排序,过滤等功能......

编辑:plalx在Eben Roux的回复中将其钉死。

ProjectName/
    IdentityAndAccess/
        Application/
            Command/
                AuthenticateUserCommand.php
                ChangeEmailAddressCommand.php
                ChangeUserPasswordCommand.php
                ChangeUserPersonalNameCommand.php
                ...
            Data/
                UserData.php
                UserRightsData.php (POPO containing User infos and a list of rights)
                RightData.php (Single comment infos)
            UserApplicationService.php
            UserQueryService.php
        Domain/
            Model/