域驱动设计-ddd-如何正确识别Value对象



我正在为我的实体建模,并且已经为此奋斗了很长一段时间。这是我的Person实体:

Person
    ID
    Name
    Email
    Password
    City
    Phone
    Biography
    Rating
    Description

我曾尝试将这些属性划分为Value Object,但到目前为止,我只能将它们转换为VO(例如,City是一个由城市名称和国家名称组成的VO)。

我是否应该尝试创建更大的VO,例如将EmailPassword组合到Credentials VO中?我是不是对VOs的分离太深了?

非常感谢任何帮助

[编辑]

经过一些讨论,似乎最好的解决方案是将每个属性都保留在自己的VO中,但电子邮件和密码除外,它们应该分组在"凭据"VO中。

Value对象是由值唯一标识的对象,即相等是由值来实现的,而不是提供唯一性的显式属性(如ID)。如果两个值对象的所有字段都是相等的,则它们是相等的

当试图识别它们时,请遵循领域专家使用的语言。他们在讨论人物时会用什么词?它们是指凭据,还是指电子邮件和密码?

还要查找始终一起使用的属性组。例如,如果Password总是与Email一起使用,那么将它们分组到Credentials对象中是有意义的,因为您可以在那里推送行为(即Credentials.Valide())

[更新]

以下所有属性都是值对象的候选者,这取决于需要强制执行的不变量

名称

  • 名称有最小/最大值吗
  • 有不允许使用的字符吗

电子邮件

  • 是有效的电子邮件地址吗
  • 两个人可以有相同的电子邮件地址吗

密码

  • 最小/最大长度
  • 必需的字符
  • 无效字符

手机

  • 这是一个有效的电话号码吗
  • 你如何处理国际拨号代码

评级

  • 评级是否允许有最小值和最大值
  • 它是如何计算的?(它是经过计算的吗?)

描述

传记

城市

等等。。。。

如果为上述概念创建Value对象,而不是使用int或string等基元值,则可以将业务规则封装在值对象中。

如果您将电子邮件和密码结合使用,则可能需要将它们合并为Credentials Value对象。即使用凭据登录等。您仍然可以访问凭据。如果您需要在凭据对象之外使用电子邮件,请发送电子邮件。

您所拥有的看起来可疑的是一个数据结构(CRUD)。在适当的DDD中,您从"创建人员"这样的业务案例开始,然后找到代表人员概念的模型。

该模型由一组组件和业务规则定义。您的组件通常是VO,因为它们是表示次要概念的模型,可以表示为没有明确标识的简单或组合值,并且它们封装了特定的业务约束。例如,Email VO确保您具有有效的电子邮件值。

你应该让域告诉你创建更大的VO是否有意义;通常你从一个VO开始,然后发现它是由其他VO组成的。一般来说,我们从上到下。你可以在这里看到一个建模示例。

当你没有领域专家时,这很难,但你仍然可以尝试在商业案例中思考,并为每个案例确定任何特定的模型。如果您最终得到的主要是简单的结构和一些数据验证规则,那么也许您有一个足够简单的域来使用CRUD方法。

不要试图强加特定的领域模型结构,您需要从用例的角度进行领域建模。

我是否应该尝试创建更大的VO,例如将电子邮件和密码放在一个凭据VO中?

只有当两者倾向于一起使用时,才应该这样做。如果他们不这样做,留下他们也没关系。

请注意,有时,如果需要支持的不变量数量足够高,足以证明引入新概念的合理性,那么将单个属性提取到其自己的值对象中是有意义的。查看本文以了解更多详细信息。

并不总是清楚域中的概念是值对象或实体,不幸的是,没有客观属性可以用来了解概念是否是值对象。这完全取决于问题域,概念可以是一个域模型中的实体,也可以是另一个域中的值对象。大多数时候,money类是一个值对象,但并不是所有的money对象都是值对象。如何找到一个值对象?首先,您应该检查身份的概念,如果它在结构上是相等的(如果对象值相同,则意味着两个对象是相同的,而不是对象的id),您可以安全地替换具有相同属性集的类的实例。这是一个好迹象,表明这个概念是一个价值对象。

思考值对象的一个好方法是,如果它是一个整数,你真的在乎整数5是否和你在其他函数中使用的5相同吗?绝对不是应用程序中的所有5个都是相同的,无论它们是如何实例化的。这就使得integer本质上是一个值对象,现在问你自己域中的对象像一个整数吗?若答案是肯定的,那个么它就是一个值对象。此外,值对象是不可变的,并且作为实体更轻。

相关内容

  • 没有找到相关文章

最新更新