我有一个名为User的聚合根。
下面是如何建模的示例:
User: {
id: string
username: string,
email: string,
auth: LocalAuth {
password: string
}
}
在我的应用程序中,我有一个 API 路由 -发布/users/id/password
- 允许用户更改其密码。
为了更改他们的密码,我们必须确保用户输入他们的旧密码。请求模型应如下所示:
{
oldPassword: string
newPassword: string
newPasswordRepeating: string // in case of user errors
}
处理此请求的控制器应执行以下操作:
- 检查旧密码是否等于当前密码
- 检查新密码是否有效
- 更新用户数据
- 返回更新的用户数据
为了处理这样的业务逻辑,我可以创建一个名为PasswordUpdate(idk..)的VO模型。此 VO 可以将验证逻辑封装在自己的模型中。
这种实现是否忠实地遵循 DDD 规则?
因为就我而言,此 VO 永远不会包含在聚合根中,也不会存储。目的只是使用域模型对密码更新进行建模。
这种实现是否忠实地遵循 DDD 规则?
非常简短的回答:继续前进。
简短的回答:无论如何,DDD警察都不会来追捕你,所以不要想太多。
宽泛的回答:我发现Evans对价值对象的描述有点混乱,因为他从Java的经验中汲取
了经验。但是如果你仔细观察,就会发现Evans正在提议创建一种领域特定的语言,你可以用它来描述模型的行为。 值对象正在做一些事情:它们为您提供特定于域的类型(以便类型系统可以尽可能帮助限制某些类型错误的频率),它们为您提供特定于域的语义(而不是坚持所有域行为都通过对域无关原语的操作来描述), 它们在域行为和域状态的内存表示形式之间提供了一个隔离层。
它的价值不仅限于"领域模型";你应该随意地将这种抽象应用到任何有意义的地方。
但。。。在您描述的情况下,您应该注意一个特定的陷阱。
域模型是您应该能够积极更改以满足业务需求的东西,这当然可以包括更改值对象的实现。
但是,消息应保守地更改。 消息是 API 的一部分。 如果我们希望能够使用不同的节奏发布兼容的客户端和服务器,那么我们需要它们之间的接口稳定。 消息不应该携带域规则(那些属于模型的规则),它只是状态的表示形式。
"验证"通常发生在我们获取消息(API 的一部分)并将其转换为模型理解的值时。