我对领域驱动设计并不熟悉,最近开始为项目创建一个领域模型。目前还没有决定使用什么 ORM(尽管我可能会选择 NHibernate),我正在努力确保我的值对象只是值对象。
我有一些几乎没有行为的值对象,除了封装“类似”的术语外:
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”,所以如果我要访问“Referral”,我可以这样写代码: case.social.referral(Case,Social和Referral都是类,一个Case里面只有一个Social,而一个Social里面只有一个Referral)。现在我打字的时候看一下,我不认为我需要在“Referral”里加入一个“Case”,因为我可以通过“Social”实体访问它,对吗?
现在,在我的脑海中,毫无疑问这应该是一个值对象(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类只有内在类型(字符串、整数)。因此我不确定它是否应该成为实体,或者是否可以保持为值对象,我只需要配置我的ORM,使用它们自己的表和一个私有/受保护的ID字段来使用1:m关系,以便ORM可以将其持久化到数据库。
另外,我应该为我的每个类选择规范化的表,还是不用?我认为只有当有可能将多个类的实例分配给实体或值对象时,并/或者有可能与其中一些对象具有集合1:m关系时,我才需要为每个类使用一个表。对于一些具有内在类型的值对象,我没有问题使用单个表,但对于嵌套类型,我认为使用规范化的表会更有优势。对此有什么建议吗?
对于这些问题我提出了许多疑问:
1)对于我的值对象,我需要一个替代标识符(例如NHibernate)吗?
2)如果答案是肯定的,那么这个标识符是否需要是私有/受保护的,以便我的值对象在概念上“保持”为值对象?
3)值对象可以包含其他值对象(例如,列表中的值对象),还是这构成实体?(我认为答案是否定的,但在进一步进行之前最好确认一下。)
4)从聚合根中向下几级的值对象需要对聚合根进行引用吗?(我认为不需要,这可能是我在编写模型时疏忽了,有人同意吗?)
5)当使用ORM将更简单的值对象映射到属于我的实体的同一个表时,可以针对某些内容(例如嵌套类型和/或具有集合属性的类型,这些属性需要它们自己的表以进行1:m关系)使用规范化的表吗?
谢谢您。