DDD:值对象中是否有列表?

Mig*_*l G 7 c# domain-driven-design nhibernate-mapping value-objects

我不熟悉域驱动设计,最近我开始为项目创建域模型.我还没有决定使用ORM(虽然我可能会选择NHibernate)而且我目前正在努力确保我的Value Objects应该就是这样.

我有一些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.
Run Code Online (Sandbox Code Playgroud)

这个特殊的类有一个参考"案例",这是两个级别,所以如果说我要访问推荐我可以去:case.social.referral(案例,社交和推荐都是所有类,有一个单一的社交在一个案例中,社交中有一个推荐).现在,当我输入它时我正在查看它,我认为我不需要推荐中的案例,因为它可以通过社交实体访问,对吗?

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

现在转到我的标题问题:VO应该有一个集合,(在我的情况下是一个List)里面吗?我只能将其视为数据库中的一对多关系,但由于没有身份,因此使类成为实体似乎不够.以下是代码:

public class LivingSituation {
    private IList<AdultAtHome> AdultsAtHome { get; set; }
    public ResidingWith CurrentlyResidingWith { get; set } // this is an enum
} // etc, etc.
Run Code Online (Sandbox Code Playgroud)

这个类目前没有Id,而AdultsAtHome类只有内在类型(string,int).所以我不确定这是否应该是一个实体,或者它是否可以作为VO保留,我只需要使用自己的表和私有/受保护的Id字段将我的ORM配置为使用1:m关系,以便ORM可以持久保存到DB.

另外,我应该为每个课程使用规范化表格吗?我想我只需要为每个类使用一个表,当有可能将类的多个实例分配给实体或值对象时和/或有可能与这些对象中的某些对象具有集合1:m的关系.对于具有内部类型但具有嵌套类型的某些值对象使用单个表我没有问题我认为使用规范化表是有利的.对此有何建议?

很抱歉这个问题很冗长:

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

2)如果#1是肯定的,那么这需要私有/保护,以便我的值对象"保持"概念中的值对象吗?

3)值对象可以具有其他值对象(例如,列表)还是构成实体?(我认为对此的答案是否定的,但在进一步开展之前,我更愿意确定.)

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

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

再次感谢.

Vij*_*tel 10

这里这里查看相关问题的答案


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

2)如果您可以使用私人/受保护的ID属性,那么很棒.或者,您可以使用显式接口来"隐藏"ID属性.

但是,在阅读您的问题时,您是否建议看到ID属性的开发人员会自动认为该对象是一个实体?如果是这样,他们需要(重新)训练.

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

  • 这应该是非常罕见的
  • 它应该只引用其他VO

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

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

5)是的.不要忘记DDD是持久无知(在理想世界!).


然而...

我认为推荐应该是一个实体.想象一下这些对话:

会话1:

  • 汤姆:"嘿乔!你能给我David Jone的推荐吗?"
  • 乔:"哪一个?"
  • 汤姆:"对不起,我的意思是推荐第123号"

会话2:

  • 汤姆:"嘿乔!你能给我David Jone的推荐吗?"
  • 乔:"哪一个?"
  • 汤姆:"我不在乎 - 只要给我任何东西"

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

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

希望有所帮助!