[英]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.