如何在 DDD 中命名和实现结果集行?
How to name and implement Result set rows in DDD?
在 DDD 中,您有一个具有唯一标识符(ID 或 UUID)的实体。通常一个实体代表数据库中的一个可存储行table。我的存储库可以加载单个实体 (findById) 或一次加载所有实体 (findAll)。
但现在必须编写一个特殊且非常复杂的查询,并连接到其他 table。结果集不再是一个特殊的(用户)实体,因为我从多个 table 中选择了不同的字段,带有别名等等。根据查询,结果可能不包含 id。
我已经成功地将这些行合并到一个新的对象集合中,但是却在为那个东西的名称(和类型)苦苦挣扎。
我的问题是:
如何在 DDD 中对来自自定义查询的此类行进行命名和分类?
首先,你应该避免查询你的领域模型,除非你真的在一个特定的聚合之后。即使这样,根据您的设计,您也可能无法获得所需的数据。
典型的建议是使用专门的查询层,并可能使用代表所需数据的读取模型。该读取模型可以根据需要进行类型化或松散化。例如,如果 name/value 对的列表可以解决问题,也许您可以选择 that.
这些查询实际上并不是域的一部分,因此在建模方面不属于域驱动设计。但是,它们作为您整体 architecture/approach.
的一部分很重要
更新:
回复@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
。
根据我的要求,我会使用合适的 return object/structure/type.
这里好像需要查询服务
DDD 非常适合 CQRS,我相信您想要的结果是只读的。
在这种情况下,您可以根据需要创建一个特殊对象:UserData,如果用户包含一些其他关系,例如角色集合或权利,您可以将其称为 UserRightsData,例如,并从 UserQueryService 中获取它。
查询服务通常在应用层。
如果您想要非只读结果,而不是您可以操纵和保留的普通实体,那么您需要向我们提供更多详细信息。特别是,您应该能够从存储库加载该实体,调用域操作,并通过应用程序服务持久化它。
查询服务非常适合视图、表格和数据显示,具有排序、过滤等...
编辑:plalx 在 Eben Roux 的 post.
的回应中指出了它
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/
在 DDD 中,您有一个具有唯一标识符(ID 或 UUID)的实体。通常一个实体代表数据库中的一个可存储行table。我的存储库可以加载单个实体 (findById) 或一次加载所有实体 (findAll)。
但现在必须编写一个特殊且非常复杂的查询,并连接到其他 table。结果集不再是一个特殊的(用户)实体,因为我从多个 table 中选择了不同的字段,带有别名等等。根据查询,结果可能不包含 id。
我已经成功地将这些行合并到一个新的对象集合中,但是却在为那个东西的名称(和类型)苦苦挣扎。
我的问题是:
如何在 DDD 中对来自自定义查询的此类行进行命名和分类?
首先,你应该避免查询你的领域模型,除非你真的在一个特定的聚合之后。即使这样,根据您的设计,您也可能无法获得所需的数据。
典型的建议是使用专门的查询层,并可能使用代表所需数据的读取模型。该读取模型可以根据需要进行类型化或松散化。例如,如果 name/value 对的列表可以解决问题,也许您可以选择 that.
这些查询实际上并不是域的一部分,因此在建模方面不属于域驱动设计。但是,它们作为您整体 architecture/approach.
的一部分很重要更新:
回复@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
。
根据我的要求,我会使用合适的 return object/structure/type.
这里好像需要查询服务
DDD 非常适合 CQRS,我相信您想要的结果是只读的。
在这种情况下,您可以根据需要创建一个特殊对象:UserData,如果用户包含一些其他关系,例如角色集合或权利,您可以将其称为 UserRightsData,例如,并从 UserQueryService 中获取它。
查询服务通常在应用层。
如果您想要非只读结果,而不是您可以操纵和保留的普通实体,那么您需要向我们提供更多详细信息。特别是,您应该能够从存储库加载该实体,调用域操作,并通过应用程序服务持久化它。
查询服务非常适合视图、表格和数据显示,具有排序、过滤等...
编辑:plalx 在 Eben Roux 的 post.
的回应中指出了它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/