价值对象是如何保存和加载的?

13

由于没有值对象的存储库,我该如何加载所有值对象?

假设我们正在建模一个博客应用程序,并且有以下类:

  • Post(实体)
  • Comment(值对象)
  • Tag(值对象)
  • PostsRespository(存储库)

我知道当我保存新的post时,它的tags会与之一起保存在同一个表中。但是如何加载所有帖子的所有标签呢? PostsRespository是否应该有一种方法来加载所有标记? 我通常这样做,但我想知道其他人的意见。

3个回答

12

我正在寻找更好的解决方案,然后我发现了这篇文章:

http://gojko.net/2009/09/30/ddd-and-relational-databases-the-value-object-dilemma/

这篇文章非常好地解释了为什么价值对象和数据库之间存在很多混淆。这里有一句话我特别喜欢:

  • "持久性并不是把所有东西都转换成实体的借口。"

Gojko Adzic给我们提供了三种保存我们的价值对象的替代方法。


关系型数据库和ORM经常会让我们意外地创建实体。http://www.jefclaes.be/2013/05/accidental-entities-you-dont-need-that.html - JefClaes
如果我将值对象保存在文本列(选项3)中,我该如何对该值对象执行原子更新? @yeraycaballero - Po-Ying Chen
@yeraycaballero 写得非常好的一篇文章,对我帮助很大。谢谢。 - Mohammad

3
我目前正在处理类似的例子。一旦您需要唯一地引用标签,它们就不再是简单的值对象,可能会变得更加复杂。我决定将它们作为自己的实体,并创建一个单独的存储库来检索它们。在大多数情况下,它们与帖子一起加载或保存,但当它们单独需要时,使用其他存储库。
希望这有所帮助。
编辑: 部分归功于这篇文章,我决定稍微重构我的应用程序。您是正确的,我可能错误地将标签作为实体。此后,我已更改我的应用程序,使标签只是字符串,而帖子存储库处理所有关于标签的存储要求。对于需要帖子的操作,它们与其一起加载标签。对于任何仅需要标签或标签列表的操作,存储库都有相应的方法。

谢谢你的回答。所以你有一个TagsRepository。数据库中也有一个Tags表吗? - yeraycaballero
我其实还没有决定使用哪种数据库。我可能不会使用单独的数据库,而是强烈考虑像Mongo或Couch这样的对象或文档数据库解决方案。 - smaclell

0

这是我对如何解决这类问题的看法,以及我目前在实践领域驱动设计(DDD)时的做法。

如果您正在编辑某个需要添加和删除标签的内容,比如一个帖子,那么标签可能是实体(entities),但也可以作为值对象(value objects)一起加载和保存。我个人倾向于使用值对象,除非需要修改该对象,但我也意识到实体对象建模为只读的“快照”与没有身份标识的实际值对象之间存在区别。棘手的部分在于,有时您通常认为是键的东西可能是值对象的一部分,只要在该上下文中不被用作身份标识,而我认为标签属于这个范畴。

如果您正在编辑标签本身,则可能是一个单独的有界上下文(bounded context),或者至少是一个单独的聚合(aggregate),其中标签本身是聚合根,并通过仓储(repository)进行持久化。请注意,在这个上下文中代表标签的实体类不必与用于帖子聚合的标签实体类相同。

如果您要在显示上列出可用的标签,仅供只读目的,例如提供选择列表,那么这可能是一个值对象列表。这些值对象可以放在领域模型中,但主要是为了支持用户界面而不是实际的领域。

如果有人认为我的想法是错误的,请随时发表意见,但这是我一直以来的做法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接