我偶然发现了一个问题:“我无法将域模型拆分为聚合根”。
我是DDD的初级开发人员和新手。我真的很想了解它,但有时确实令人困惑。
在这一点上,我想简要描述一下我的域名。
我的目的是为用户提供机会自行创建任何类型的文档。用户可以创建新型的文档。每个新类型均包含其属性。然后,该应用程序的用户可以根据其类型创建具体的文档。用户还可以发送文档以供批准。每种类型的批准流程都不同。
因此,我们有以下模型:
还有其他模型,但我认为它们没有道理。
如您所知,这里我应用数据模型的实体属性值(EAV)模式。您可以看到显示数据库中关系的diagram。
我的问题是:
除了我已经描述的之外,我的模型中还有很多实体。
我认为Document绝对是我的域中的聚合根。因为汇总的诸如ApprovalProcess之类的东西无法生存。
这是第一个问题:
ApprovalProcess包含其步骤。每个步骤都是可变的,因此是一个实体。步骤的状态可以更改。 ApprvalProcess的状态取决于其步骤。在这里,我们有一个业务不变式:“只有批准了所有步骤,才能批准ApprovalProcess。”
我认为它是一个聚合根,因为它具有业务不变性,并且包含无法生存的实体。而且,我们不想允许直接访问其步骤以保持ApprovalProcess的一致性。
我是否误认为ApprovalProcess是聚合根?可能只是一个汇总? 一个聚合根可以作为一部分存在于另一个根中吗?这是否意味着ApprovalProcess只是聚合的,因为Document负责访问其各个部分?但是,当批准ApprovalProcess的步骤时,Document会将操作委托给ApprovalProcess。
例如:
Document doc = new Document(...);
doc.SendForAooroval(); //ApprovalProcess is created.
doc.ApproveStep(int stepId); // Inside the method Document delegates responsibility for approvement to ApprovalProcess.
或者我应该分别离开Document和ApprovalProcess。因此,文档将按身份引用ApprovalProcess。我们有以下情形:
Document doc = documentRepository.Get(docId);
doc.SendForAooroval();// A domain event "DocumentCreatedEvent" is raised.
DocumentCreatedEventHandler:
ApprovalProcess approvalProcess = new ApprovalProcess(event.DocId); // ApprovalProcessCreatedEvent is raised
approvalProcessRepository.Add(approvalProcess);
approvalProcessRepositroy.UnitOfWork.Save(); //commit
但是,如果ApprovalProcess的状态更改,则Document的状态也会更改。批准流程被批准,然后文档也被批准。另一个词ApprovalProcess是Document状态的一部分。只有这样,我们才能知道文档已获批准。
还有我遇到的最大问题:
DocumentType也是一个聚合根。它由其属性和ApprovalScheme组成。为了使我的解释尽可能简单,我还没有提到ApprovalScheme。 ApporvalScheme也由某些实体组成。这只是DocumentType的批准流程。根据具有Document的DocumentType的ApprovalScheme创建ApprovalProcess。没有DocumentType不能存在ApprovalScheme。一对一的关系。
文档通过标识引用其DocumentType。正确吗?
在开始执行此任务时,我认为DocumentType应该是Document的一部分。
DocumentType有许多文档,但是在我的域中没有任何意义。它不代表DocumentType的状态。 DocumentType可以标记为已删除,但不能删除。
Document和DocumentType是两个不同的聚合根。我说的对吗?
非常感谢您的阅读。非常感谢您的关注和帮助! 对不起,我的英语不好。
答案 0 :(得分:1)
我是否误认为ApprovalProcess是聚合根?可能是 只是总数?一个聚合根可以存在于另一个根中吗 这是一部分吗?
这些问题对我来说毫无意义。集合是一组实体和值对象,其中一个实体是该组的父级。聚合根是聚合的父实体。一种特殊情况是聚合只是一个实体。当然,单独的实体是集合,而实体当然是集合的根。
我认为我将从另一个角度尝试为您的问题建模:作为状态机。
我将ApprovalProcess视为文档遵循的流程,而不是实体。我不知道该过程的流程图,但是我想您所说的“步骤”将是文档在该过程中可以具有的“状态”,并且您需要在各步骤之间进行转换,因此首先创建一个新文档,这是一个开始,并且在文档的整个生命周期中,它都会一步到另一步,直到达到最后一步(例如,已批准的文档)。
因此,文档实体将具有更改其状态的行为。
例如,在Java中,您可以使用枚举实现状态模式(状态机)。