代码之家  ›  专栏  ›  技术社区  ›  koen

如何为价值对象关系建模?

  •  1
  • koen  · 技术社区  · 15 年前

    背景:
    我有一本实体书。一本书可以有一个或多个描述。描述是值对象。


    一个描述可以比另一个描述更具体。例如,如果一个描述包含书的内容和封面的外观,那么它比只讨论封面外观的描述更具体。我不知道如何对此建模以及如何让存储库保存它。了解这些关系不是本书或本书描述的责任。其他一些对象可以处理这个问题,然后要求存储库保存关系。但是BookRepository.AddMoreSpectDescription(描述,MoreSpectDescription)对于存储库来说似乎很难保存。

    3 回复  |  直到 15 年前
        1
  •  7
  •   eduncan911    15 年前

    另外两个答案是一个方向(+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
  •   jason    15 年前

    第二,为什么要尝试建立评论之间的关系模型?我看不出他们之间有什么天然的关系。”“比”更具体是太模糊了,作为一种关系是没有用的。

    如果你很难对情况进行建模,这表明可能没有关系。

        3
  •  1
  •   Nathan Hughes    15 年前

    我同意杰森的观点。我不知道你的理由是什么让评论成为有价值的对象。