我不太熟悉领域驱动设计,最近我开始为项目创建领域模型。我还没有决定使用 ORM(尽管我可能会选择 NHibernate),并且我目前正在努力确保我的值对象应该就是这样。

我有一些 VO 除了封装“类似”术语之外几乎没有任何行为,例如:

public class Referral {
    public Case Case { get; set; } // this is the a reference to the aggregate root
    public ReferralType ReferralType { get; set; } // this is an enum
    public string ReferralTypeOther { get; set; }
} // etc, etc.

这个特定的类有一个对“案例”的引用,它是两个级别的,所以如果说我要访问推荐,我可以去:case.social.referral(Case、Social 和 Referral 都是类,Case 内有一个 Social,Social 内有一个 Referral)。现在,我在输入时查看它,我认为我不需要推荐中的案例,因为它可以通过社交实体访问,对吗?

现在,毫无疑问,我认为这应该是一个 VO,并且我计划用来将其持久保存到数据库的方法是让 NHibernate 为其分配一个代理标识符(我仍然不太清楚) ,如果有人也能详细说明这一点,它会对我有所帮助,因为我不知道代理标识符是否要求我在 VO 中已有一个 Id,或者它是否可以在没有 Id 的情况下运行)和/或受保护的 Id 属性不会暴露在 Referral 类之外(仅用于持久化到数据库的目的)。

现在回答我的标题问题:VO 中是否应该有一个集合(在我的例子中是一个列表)?我只能将其视为数据库中的一对多关系,但由于没有标识,因此似乎不足以使该类成为一个实体。下面是代码:

public class LivingSituation {
    private IList<AdultAtHome> AdultsAtHome { get; set; }
    public ResidingWith CurrentlyResidingWith { get; set } // this is an enum
} // etc, etc.

该类当前没有 Id,而 AdultsAtHome 类只有内在类型(字符串、整数)。所以我不确定这是否应该是一个实体,或者它是否可以保留为 VO,我只需要配置我的 ORM 以使用它们自己的表和私有/受保护的 Id 字段来使用 1:m 关系,以便ORM可以持久化到DB。

另外,我是否应该为每个班级使用标准化表格?我认为当有可能将类的多个实例分配给实体或值对象和/或有可能与其中一些对象建立 1:m 关系时,我只需要为每个类使用一个表。我对某些具有内在类型的值对象使用单个表没有问题,但对于嵌套类型,我认为使用规范化表会更有利。对此还有什么建议吗?

抱歉,我对多个问题如此冗长:

1) 我的值对象是否需要一个代理标识符(例如 NHibernate)?

2)如果#1是肯定的,那么这是否需要私有/受保护,以便我的值对象在概念上“仍然是”值对象?

3)一个值对象可以有其他值对象(例如,一个列表)或者它会构成一个实体吗?(我认为答案是否定的,但我更愿意在继续下一步之前确定一下。)

4) 我是否需要从比聚合根低几级的值对象引用聚合根?(我不认为我这样做,这可能是我在编写模型时的疏忽,有人同意吗?)

5) 在让 ORM 为更简单的值对象进行映射的同时,是否可以对某些事物使用规范化表(例如嵌套类型和/或以集合作为属性的类型,无论如何都需要它们自己的表来实现 1:m 关系)属于我的实体的同一张表?

再次感谢。

有帮助吗?

解决方案

看看相关问题的回答 这里这里


1) 是的 - 如果 您将 VO 存储在它们自己的表中

2) 如果您可以使用私有/受保护的 ID 属性,那就太好了。或者,您可以使用显式接口来“隐藏”ID 属性。

但是,仔细阅读您的问题,您是否建议看到 ID 属性的开发人员会自动假设该对象是一个实体?如果是这样,他们需要(重新)培训。

3) 是的,可以,但有以下限制:

  • 应该是比较少见的
  • 它应该只引用其他 VO

另外,请考虑一下:VO 不应该 停在附近。每次需要时重新创建整个 VO 是否容易/高效?如果没有,请将其设为实体。

4) 取决于您想要如何实施 聚合锁定. 。如果你想使用 阿延德的解决方案, ,答案是肯定的。否则,您将需要一种机制来将对象图遍历回聚合根。

5) 是的。不要忘记 DDD 是 执着无知 (在理想的世界中!)。


然而...

我相信推荐应该是 实体. 。想象一下这些对话:

对话1:

  • 汤姆:“嘿乔!你能给我大卫·琼斯的推荐吗?”
  • 乔:“哪一个?”
  • 汤姆:“抱歉,我是说推荐号 123”

对话2:

  • 汤姆:“嘿乔!你能给我大卫·琼斯的推荐吗?”
  • 乔:“哪一个?”
  • 汤姆:“我不在乎——给我一个就行了”

对话 1 表明推荐是 实体, ,而对话 2 表明它是一个 VO。

还有一件事:做 Referral.ReferralType 在它的生命周期中发生变化(还有另一个暗示它应该是一个实体)?如果它 改变的话,考虑使用多态性,让NH来处理。

希望有帮助!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top