我对DDD很陌生,并且一如既往当你围绕着有趣的概念时,你将不可避免地达到某一点或某种情况,让你感到不确定你刚学到的东西应该如何应用于某些问题
假设您有两个与用户不同的日期:DateOfBirth
和DateOfRegistration
。将两者分别实现为两个不同的值非常有意义。这很简单,很棒。
现在,让我们假设应用程序Users
可以参与Projects
。一个项目可以有多个members
和一个创建(拥有)它的用户。
因此ProjectMembers
和ProjectOwner
都是Users
。
在Project
中有两种方法可以实现此功能:
答:强类型 - 创建类ProjectMember
和ProjectOwner
然后“行动”为值对象。让它们作为包装器工作,甚至扩展User
类。
B:懒惰方法 - 只需根据所需的行为/期望命名方法和参数,然后推送User
对象。
在我看来,遵循B意味着放弃DDD原则。
遵循A将导致数十个课程,其中许多人不会做任何事情,而是强制执行类型安全。
我很困惑,因为与简单日期相比,用户是实体甚至是聚合根,同时也更复杂。
A,B还是第三种选择?
答案 0 :(得分:2)
在A之后会导致数十个课程,其中许多课程不会做任何事情,而是为了加强类型安全。
不,他们还记录了您在域模型中发现的区别;您可能还不了解这些区别如何影响模型的行为,但您已经获得了占位符,并且使用了正确的语言(假设您的名字使用的是无处不在的语言),因此您的域模型更多与业务紧密结合。
那没什么。
我很困惑,因为与简单日期相比,用户是实体甚至是聚合根,同时也更复杂。
所以要记住一件事 - 作为一种习惯,你不要从聚合之外引用保护它们的实体。所以ProjectOwnerId
而不是ProjectOwner
。
对于不做任何有趣事情的类型(标识符特别是一个不透明的东西,除了与其他标识符比较之外没什么作用),你 可能会使用相同的类型和一点语法糖来确保类型安全。
例如,Identifier<T>
隐式地为您提供Identifier<ProjectMember>
和Identifier<ProjectOwner>
,而不是要求您为每个标识符拼写生成不同的实现