识别Facebook域模型中的实体和价值对象

时间:2013-12-13 14:13:28

标签: c# java facebook domain-driven-design

如果我正在建立一个社交网络,用户可以只分享帖子,我会将用户建模为实体,而将帖子设为收藏值对象

然而,在Facebook帖子中可以被其他用户喜欢。帖子可以有评论。其他用户也可以喜欢评论。

我一直认为实体具有我们关心的身份,但Value对象没有。

引入评论和喜欢的概念有点提升了帖子的重要性。现在我需要确定哪个评论与哪个帖子有关。同样,我需要确定哪个用户喜欢哪个帖子或评论。

如果我有2个帖子的确切措辞“有些虚拟帖子在这里” ,但第一个是User1和User2喜欢,而第二个喜欢User3和User4,那么我应该得出结论,这些是不同的帖子。但是,仅仅比较帖子的身份会更容易。

TL; DR

引入与价值对象的关系是否会将其推广到实体?

3 个答案:

答案 0 :(得分:1)

让我们清理一下:

  • 实体始终拥有ID,因为无论其他值如何,您都希望识别它们。
  • 值对象(VO)封装了一个值并且可以互换,您不关心该对象,您只关心该值。您使用VO而不仅仅是值(假设它不是复合值)的原因是VO始终处于有效状态并且“保证”您正在使用有效值。

从VO到实体的没有促销 ,他们应该从一开始就为正确的域概念建模。

在您的方案中,帖子,评论和用户始终是实体。帖子没有评论,they are associated with comments是用户,帖子和评论的用例。

您将拥有一个LikesTracker或类似内容,可以将用户的喜欢与帖子或评论相关联。

我不同意@Alexey Raga建议的结构,因为这是错误的(CRUD)建模。首先,User和Post是Aggregate Roots,而不是Aggregates(表示一组与上下文相关的概念)。我不明白为什么Like应该是VO,但是无论如何,Like和Comments的集合不是Post概念定义的一部分,它们不属于那里。

该结构对于读取(视图)模型有意义,但不适用于域模型。

答案 1 :(得分:0)

我不是DDD的专家,但...... 实体是存储库返回的对象。要访问值对象,您需要从存储库中提取实体,然后从实体中获取value-object。

所以我认为你应该问自己一个问题:我希望直接填充视图的数据库中有哪些对象? IMO您将需要从db获取用户,例如显示用户配置文件,更改密码等。因此用户可能是您的实体。至于帖子,取决于。如果您计划只显示用户帖子列表,Post可以是值对象。但是,如果您计划实施帖子搜索(例如按日期范围),那么Post应该是您的实体。

总结一下。这一切都取决于你想要实现的目标。

答案 2 :(得分:0)

我认为发布一个价值对象是不明智的。 查看域和域周围的语言,我们可以看到Post可能是一个实体(聚合)本身。正如您所提到的,该域名在帖子方面“会谈”。

帖子还提供了一些行为,可以采取行动。例如,您可能希望获得指向特定帖子的链接,或者共享特定帖子等。

另一个(技术)原因是不发布一个价值对象是你可能不想在你想要只展示一个特定的一个帖子时加载所有帖子的用户聚合。

所以Post可以建模为聚合,可以有一些AuthorId等。

然而,

喜欢可以视为值对象。因此,帖子和评论可以有一系列喜欢。

至于评论,我可能会将它们建模为Post聚合中的实体。请记住,实体在其聚合实例范围内具有ID ,因此每个帖子可以包含注释#1,注释#2等。 实体可能有自己的结构和行为(例如,他们自己的喜欢集合)。

要考虑的另一件事是聚合是一个事务边界。无需在同一事务中包装User和Post,它们的行为完全独立,因此User和Post是不同的Aggregates。

所以我可能会从以下结构开始:

  • 用户(聚合)

  • 发布(聚合)

    • Collection [Like](每个Like是一个Value Object)
    • 收藏[评论](每个评论是一个实体)
      • 每个评论都有一个[喜欢]
      • 的集合

希望它有所帮助。