Architecture DDD-从实体派生值对象

Architecture DDD-从实体派生值对象,architecture,domain-driven-design,Architecture,Domain Driven Design,我是DDD的新手,和往常一样,当你围绕着有趣的概念思考时,你将不可避免地达到一个点或一种情况,这使你感到不确定,你刚刚学到的东西在面对某些问题时应该如何应用 假设您有两个关于用户的不同日期:出生日期和注册日期。将它们作为两个不同的值分别实现非常有意义。那很容易,很好 现在,让我们假设在应用程序中,用户可以参与项目。一个项目可以有多个成员和一个拥有它的用户 因此,ProjectMembers和ProjectOwner都是幕后用户 有两种方法可以在Project中实现此功能: 强类型-创建类Proj

我是DDD的新手,和往常一样,当你围绕着有趣的概念思考时,你将不可避免地达到一个点或一种情况,这使你感到不确定,你刚刚学到的东西在面对某些问题时应该如何应用

假设您有两个关于用户的不同日期:出生日期和注册日期。将它们作为两个不同的值分别实现非常有意义。那很容易,很好

现在,让我们假设在应用程序中,用户可以参与项目。一个项目可以有多个成员和一个拥有它的用户

因此,ProjectMembers和ProjectOwner都是幕后用户

有两种方法可以在Project中实现此功能:

强类型-创建类ProjectMember和ProjectOwner,作为值对象。要么让它们作为包装器工作,要么甚至扩展用户类

B:惰性方法-只需根据所需的行为/期望命名方法和参数,并推送用户对象

在我看来,遵循B意味着放弃DDD原则

遵循A将产生几十个类,其中许多类除了强制执行类型安全之外什么都不做

我很困惑,因为与简单的日期相比,用户是实体,甚至是聚合根,同时更加复杂

是A、B还是有第三种选择

遵循A将产生几十个类,其中许多类除了强制执行类型安全之外什么都不做

不,它们还记录了您在域模型中发现的区别;您可能还不了解这些区别是如何影响模型的行为的,但是您已经有了占位符,并且假设您的名字是基于普遍存在的语言,那么您的域模型将与业务更加紧密地结合在一起

那没什么

我很困惑,因为与简单的日期相比,用户是实体,甚至是聚合根,同时更加复杂

所以有一件事要记住——作为一种习惯,您不会从保护实体的聚合外部引用实体。所以ProjectOwnerId而不是ProjectOwner

对于不做任何有趣事情的类型,特别是标识符往往是一个不透明的东西,除了与其他标识符进行比较之外,它没有什么作用 可能会使用相同的类型加上一些语法上的修饰来确保类型安全

例如,Identifier隐式地为您提供标识符和标识符,而不是要求您为标识符的每个拼写生成不同的实现