我正在为我的实体建模,并且长期以来一直在努力解决这个问题。这是我的Person
实体:
Person
ID
Name
Email
Password
City
Phone
Biography
Rating
Description
我试图将这些属性划分为Value Objects,但到目前为止我只能将它们转换为VO(例如,City是使用城市名称和国家/地区名称制作的VO)。
我是否应该尝试创建更大的VO,例如将Email
和Password
放在Credentials
VO中?我是否会过分分离为VO?
非常感谢任何帮助
[编辑]
经过一番讨论后,似乎最好的解决方案是将每个属性保留在自己的VO中,但电子邮件和密码除外,应将其分组到“凭据”VO中。
答案 0 :(得分:1)
值对象是值唯一标识它们的东西。等值由值完成,而不是显式属性(如ID)来提供唯一性。如果两个值对象的所有字段相等,则它们相等
尝试识别它们时,请遵循域专家使用的语言。在讨论人们时他们用什么词?他们是指资讯,电子邮件和密码吗?
还要查看始终一起使用的属性组。例如,如果密码始终与电子邮件一起使用,则将它们组合在凭据对象中是有意义的,因为您可以在那里推送行为(即Credentials.Validate())
[UPDATE]
以下所有属性都是值对象的候选属性,具体取决于您需要强制实施的不变量
名称
电子邮件强>
密码强>
<强>电话强>
<强>评分强>
<强>描述强>
<强>传记强>
<强>城市强>
等...
如果为上述概念创建值对象而不是使用原始值(如int或string),则可以将业务规则封装在值对象中。
如果您使用这两个内容,您可能希望将电子邮件和密码组合到凭据值对象中。即使用凭据等登录...如果您需要使用Credentials对象外部的电子邮件,您仍然可以访问Credentials.Email。
答案 1 :(得分:1)
你所拥有的东西看起来像一个数据结构(CRUD)。在正确的DDD中,您可以从“创建人员”等业务案例开始,然后找出模型代表人员概念。
模型由一组组件和业务规则定义。您的组件通常是VO,因为它们是表示次要概念的模型,可以表示为没有显式标识的简单或复合值,并且它们封装了特定的业务约束。例如,Email
VO可确保您拥有有效的电子邮件值。
您应该让域名告诉您创建更大的VO是否有意义;通常你从一个VO开始,你发现它是由其他VO组成的。一般来说,我们自上而下。您可以see here建模示例。
当您没有域专家时很难,但您仍然可以尝试在业务案例中进行思考,并确定每个案例的具体模型。如果你最终得到的主要是简单的结构和一些数据验证规则,那么你可能只有一个足够简单的域来使用CRUD方法。
答案 2 :(得分:1)
不要试图强加特定的域模型结构,需要从用例角度进行域建模。
我是否应该尝试通过将电子邮件和密码放在凭证VO中来创建更大的VO?
只有当两者倾向于一起使用时才应该这样做。如果他们不这样做,那么他们就可以了。
请注意,如果需要支持的不变量的数量足以证明引入新概念的合理性,有时将单个属性提取到其自己的值对象中是有意义的。有关详细信息,请查看this article。
答案 3 :(得分:0)
并非总是很清楚域中的概念是值对象还是实体,但是不幸的是,您无法使用任何客观属性来了解概念是否完全是值对象,这取决于问题域,一个概念可以是一个域模型中的实体,也可以是另一个域模型中的值对象。大多数时候,金钱类别是价值对象,但并非所有金钱对象都是价值对象。如何找到一个价值对象?首先,您应该检查身份的概念是否在结构上相等(这意味着如果对象的值相同,则两个对象是相同的,而不是对象的id),则可以安全地替换具有相同属性集的类的实例。很好的兆头,这个概念是一个价值对象。
思考值对象的一种好方法是考虑它是否是整数,您真的关心整数5是否与您在其他函数中使用的5相同?绝对不是您的应用程序中的所有5个都相同,无论它们如何实例化。这使整数本质上成为一个值对象,现在问自己域中的对象就像一个整数吗?如果答案为是,则它是一个值对象。而且,价值对象作为实体是不变的,而且重量更轻。