在DDD中,您有一个具有唯一标识符(ID或UUID)的实体。通常,实体表示数据库表中的可存储行。我的存储库可以一次加载单个实体(findById)或所有实体(findAll)。
但现在必须编写一个特殊且非常复杂的查询,并将其连接到其他表。结果集不再是特殊的(用户)实体,因为我从具有别名的多个表中选择了不同的字段,依此类推。根据查询,结果可能不包含id。
我已成功地将这些行水合成一个新的对象集合,但却对该事物的名称(和类型)感到挣扎。
我的问题是:
如何命名和分类来自DDD中自定义查询的此类行?
答案 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/