ddd - 如何正确识别值对象?

时间:2016-07-20 12:16:34

标签: domain-driven-design value-objects

我正在为我的实体建模,并且长期以来一直在努力解决这个问题。这是我的Person实体:

Person
    ID
    Name
    Email
    Password
    City
    Phone
    Biography
    Rating
    Description

我试图将这些属性划分为Value Objects,但到目前为止我只能将它们转换为VO(例如,City是使用城市名称和国家/地区名称制作的VO)。

我是否应该尝试创建更大的VO,例如将EmailPassword放在Credentials VO中?我是否会过分分离为VO?

非常感谢任何帮助

[编辑]

经过一番讨论后,似乎最好的解决方案是将每个属性保留在自己的VO中,但电子邮件和密码除外,应将其分组到“凭据”VO中。

4 个答案:

答案 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个都相同,无论它们如何实例化。这使整数本质上成为一个值对象,现在问自己域中的对象就像一个整数吗?如果答案为是,则它是一个值对象。而且,价值对象作为实体是不变的,而且重量更轻。