DDD - 我可以使用值对象作为模型助手

时间:2018-04-12 12:14:05

标签: api model domain-driven-design value-objects clean-architecture

我有一个名为用户的聚合根 以下是其模型化示例:

User: {
  id: string
  username: string,
  email: string,
  auth: LocalAuth {
    password: string
  }
}

在我的申请中,我有一条API路线 - POST /users/id/password - 允许用户更改密码 要更改密码,我们必须确保用户输入旧密码。请求模型应如下所示:

{
  oldPassword: string
  newPassword: string
  newPasswordRepeating: string // in case of user errors
}

处理此请求的控制器应执行以下操作:

  • 检查oldPassword是否等于当前的
  • 检查newPassword是否有效
  • 更新用户数据
  • 返回更新的用户数据

为了处理这样的业务逻辑,我可以创建一个名为 PasswordUpdate (idk ..)的VO模型。这个VO可以将验证逻辑封装在自己的模型中。

这种实施是否忠实遵循DDD规则? 因为在我的情况下,此VO永远不会包含在聚合根中,也不会存储。目的只是使用域模型对密码更新进行建模。

1 个答案:

答案 0 :(得分:1)

  

这种实施是否忠实遵循DDD规则?

非常简短的回答:直接前进。

简短的回答:无论如何,DDD警察都不会追你,所以不要过度思考。

答案很广:我发现埃文斯对“价值对象”的描述是一种混乱,受到他从Java经验中吸取的影响。

但是,如果你仔细观察,发生的事情是Evans正在提议创建一种特定领域的语言,你可以用它来描述模型的行为。值对象正在做一些事情:它们为您提供特定于域的类型(以便类型系统可以协助,因为它能够限制某些类型的错误的频率),它们为您提供特定于域的语义(而不是坚持通过对域不可知原语的操作来描述所有域行为,并且它们在域行为和域状态的内存表示之间提供隔离层。

此值不限于“域模型”;你应该随意在任何有意义的地方应用这种抽象。

但是......在你描述你应该知道的情况下有一个特殊的陷阱。

域模型是您应该能够积极改变以满足业务需求的东西,当然可以包括更改值对象的实现。

但是,

消息应该保守地更改。消息是API的一部分。如果我们希望能够使用不同的节奏发布兼容的客户端和服务器,那么我们需要它们之间的接口是稳定的。消息不应该随身携带域规则(属于模型),它只是状态的表示。

“验证”通常在我们接收消息(api的一部分)并将其转换为模型理解的值时发生。