我正在努力掌握DDD背后的想法,并将它们应用到我们的宠物项目中,我有一些问题,希望有人能够回答。
该项目是一个文件管理系统。我们遇到的特殊问题涉及我们的系统处理的两个概念:Document
和DocumentStatus
的概念。
Document
有许多属性(例如标题,作者等)。用户可以在其生命周期内更改任何Document
属性。
Document
可能在任何时候都处于特定状态,例如NEW
,UNDER_REVISION
,REVISED
,APPROVED
等。我们需要知道是谁改变了那个州。
我们需要能够根据文档状态查询系统。一个示例查询将是#34;获取所有处于REVISED
状态的文档"。
"获取用户X"
已更改状态的所有文档在同一事务中需要更改Document
和DocumentStatus
的唯一时间是创建Document
时(创建文档并同时为其分配状态为NEW
)。
对于所有其他时间,UI允许更新但不能同时更新(即您可以更改文档的属性,例如作者,但不更改其状态。)或者您可以更新其状态(来自{ {1}}到NEW
)但不是它的属性。
我认为我们可以安全地考虑UNDER_REVISION
是实体和聚合根。
我们对Document
的内容进行了讨论。一种选择是使其成为DocumentStatus
聚合的值对象部分。
另一种选择是使其成为一个实体并成为其自身聚合的根。
我们还想提及我们在各种DDD文档中描述的CQRS,但我们认为这太麻烦了,特别是考虑到我们需要在Document
上执行查询。
任何指针或想法都会受到欢迎。
答案 0 :(得分:6)
您说您需要能够查看过去的状态更改,因此状态历史记录成为域概念。一个简单的解决方案如下:
StatusHistory
实体中定义Document
。 StatusHistory
是StatusUpdate
值对象的列表。StatusHistory
中的第一个元素始终反映当前状态 - 确保在创建StatusUpdate
实体时将初始状态添加为Document
值对象。根据状态历史记录需要多少额外逻辑,请考虑为历史记录本身创建专用值对象(甚至实体)。
您并没有真正说出持久层的外观,但我认为应该可以使用每种持久性机制创建针对StatusHistory
列表的第一个元素的查询。例如,使用map-reduce数据存储创建一个由Document.StatusHistory[0]
编制索引的视图,并使用该视图实现所需的查询。
答案 1 :(得分:0)
如果您只是记录当前状态,那么这很可能是一个值对象。
由于您正在编写更多符合条件 - 如果没有识别 - 数据到其中,您也打算查询它,那么这听起来好像没有DocumentStatus
就像另一个,所以一个值对象没有'这很有道理,是吗?
由
标识此外,它在上一个 DocumentStatus
的上下文中更有意义(如果您考虑的状态多于NEW
和UNDER_REVISION
)。
对我来说,这显然排除了将DocumentStatus
建模为值对象。
在 state 方面作为DocumentStatus
的属性,并遵循的概念,一切都是对象(目前正在阅读David West的对象思考),那当然可以建模为价值对象。