[英]Domain Driven Design (DDD) and database generated reports
我仍在调查DDD,但我很想知道一个潜在的陷阱。
根据DDD,聚合根不应该了解持久性,但这是否意味着整个聚合根最终都在内存中实例化了?
例如,如果不知道持久性,那么聚集根如何要求数据库进行分组和汇总大量数据?
根据DDD,聚合根不应该了解持久性,但这是否意味着整个聚合根最终都在内存中实例化了?
哦,不,比这还糟。 整个集合 (根和所有从属实体)都在内存中实例化加载。 本质上,根据定义,您需要加载所有状态以验证任何更改。
例如,如果不知道持久性,那么聚集根如何要求数据库进行分组和汇总大量数据?
您不需要执行聚合根。
域模型的主要作用是通过确保所有记录都尊重您的业务不变性来确保记录簿的完整性。 读取(例如数据库报告)不会更改记录,因此您无需加载域模型。
如果域模型本身需要报告,则通常定义一个服务提供商接口,该接口指定需要的报告,而持久性组件负责确定如何实现该接口。
根据DDD,聚合根不应该了解持久性,但这是否意味着整个聚合根最终都在内存中实例化了?
聚合根是一致性边界,因此,是的,通常将整个聚合加载到内存中以强制不变式。 如果这听起来像是一个问题,则可能暗示您的集合太大,可能需要重构。
例如,如果不知道持久性,那么聚集根如何要求数据库进行分组和汇总大量数据?
聚合不会要求数据库对数据进行分组和求和-通常,您会将聚合加载到应用程序服务/命令处理程序中。 例如:
public class SomeUseCaseHandler : IHandle<SomeCommand>
{
private readonly ISomeRepository _someRepository;
public SomeUseCaseHandler(ISomeRepository someRepository)
{
_someRepository = someRepository;
}
public void When(SomeCommand command)
{
var someAggregaate = _someRepository.Load(command.AggregateId);
someAggregate.DoSomething();
_someRepository.Save(someAggregate);
}
}
因此,您的聚合仍然忽略其持久性。 但是,您对ISomeRepository的实现并非一无所知,因此可以做任何必要的事情来完全加载聚合。 因此,在加载聚合时,您可以具有持久性实现组/总和,但是更常见的是,您可能会查询读取模型:
public class SomeUseCaseHandler : IHandle<SomeCommand>
{
private readonly ISomeRepository _someRepository;
private readonly ISomeReadModel _someReadModel;
public SomeUseCaseHandler(ISomeRepository someRepository, ISomeReadModel readModel)
{
_someRepository = someRepository;
_someReadModel = someReadModel;
}
public void When(SomeCommand command)
{
var someAggregaate = _someRepository.Load(command.AggregateId);
someAggregate.DoSomethingThatRequiresTheReadModel(_someReadModel);
_someRepository.Save(someAggregate);
}
}
您实际上并未说出用例是什么。 :)
[更新]
只是注意到标题是数据库生成的报告-完全不会通过您的域模型,它将是一个完全独立的读取模型。 CQRS在这里适用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.