1
7
另外两个答案是一个方向(+1 btw)。我是在你编辑了原始问题后进来的,所以这是我的两分钱。。。 我将值对象定义为具有两个或多个属性的对象,这些属性可以(也可以)在其他实体之间共享。它们只能在单个聚合根中共享,这也很好。事实上,他们可以(也可以)分享。 为了使用您的示例,您将“描述”定义为值对象。这告诉我,具有多个属性的“描述”可以在多本书中共享。在现实世界中,这是没有意义的,因为我们都知道每本书都有作者或出版者的大师所写的独特描述。呵呵。因此,我认为描述并不是真正的值对象,但它们本身是书本聚合根实体边界中的附加实体对象(在单个聚合根实体中可以有多个实体)。即使是重新发行的书籍、更新的版本等,描述这一细微变化的描述也略有不同。 我相信这就回答了您的问题-创建描述实体对象,并在您的主Book实体聚合根(例如Book.GetDescriptions()…)后面保护它们。这个答案的其余部分将介绍我如何处理存储库中的值对象,供阅读本文的其他人使用。。。 为了将价值对象存储在存储库中并检索它们,当我从“数据库优先”的建模方法切换到DDD方法时,我们开始涉足我自己的领域。我自己也在讨论如何在数据库中存储一个值对象,并在没有标识的情况下检索它。直到我后退一步,意识到我在做什么。。。
让我们以值对象的常见DDD示例为例,它是一个Address()。DDD指出,邮寄地址是一个完美的价值对象示例,因为价值对象的定义是谁的属性总和的对象,以创建对象的唯一性。如果某个属性发生更改,它将是一个不同的值对象。同一个值对象(其属性的总和)可以在其他实体之间共享。
因此,我有一个Person()对象和一个MailingAddress()对象,其中包含地址信息。它受my Person()聚合根目录和get/update/create方法/服务的保护。 现在,我们如何存储这些信息并在同一个家庭中的人之间共享?啊,DDD存在——您没有直接从DDD对数据存储进行建模(尽管这样做很好)。话虽如此,您只需创建一个表示Person对象的表,其中包含邮件地址的列。存储库的工作是将这些信息从数据存储中重新水合到Person()和MailingAddress()对象中,并在创建/更新操作期间将其拆分。 是的,您的数据存储中现在有重复的数据。具有相同邮寄地址的三个Person()实体现在都有该值对象数据的三个独立副本-这没关系!价值对象很容易被复制和销毁。”“复制”是DDD剧本中的最佳词语。
以上都是严格的DDD。但是,DDD只是一种“建议”,而不是生活规则。这就是为什么你可以自由地做我和其他人做过的事情,有点松散的DDD风格。如果您不喜欢复制的数据,您唯一的选择就是可以为MailingAddress()创建一个单独的表,并在其上粘贴一个标识列,并更新MailingAddress()对象,使其现在具有该标识—知道您只使用该标识将其链接到共享它的其他Person()对象(我个人喜欢第三个多对多关系表,以保持查询速度)。您将屏蔽该标识(即内部修饰符),使其不会暴露在聚合根/域之外,因此其他层(如应用程序或UI)可能不知道MailingAddress的标识列。另外,我将为MailingAddress创建一个专用存储库,并使用PersonService层将它们组合到正确的对象Person.MailingAddress()中。 对不起,我的咆哮……:) |
2
4
第二,为什么要尝试建立评论之间的关系模型?我看不出他们之间有什么天然的关系。”“比”更具体是太模糊了,作为一种关系是没有用的。 如果你很难对情况进行建模,这表明可能没有关系。 |
3
1
我同意杰森的观点。我不知道你的理由是什么让评论成为有价值的对象。
|
Tony Raimo · 域实体是否应该调用存储库? 7 年前 |
Seb · DDD只读存储库返回“值对象” 7 年前 |
tlt · 使用嵌套对象和大集合进行聚合根优化 7 年前 |
PatrickSJ · DDD,状态对象/值对象 7 年前 |
msmani · DDD更改聚合根id 7 年前 |
DuskMcDusk · 逻辑和性能中的聚合根冲突 7 年前 |