Domain driven design 实体是调用自己的行为还是参与者?

Domain driven design 实体是调用自己的行为还是参与者?,domain-driven-design,Domain Driven Design,我试图应用一些DDD概念,我只是想知道什么更有意义:实体调用自己的方法,还是用户(参与者)调用自己的方法 例如,假设我们有一个约会实体。 只有当用户是该约会的所有者时,才能取消该约会(因此我们需要检查用户是否具有适当的权限,然后才能允许该操作)。我们可以采用以下两种方法之一: pseudocode // method #1 User.Cancel(a *Appointment) result // method #2 Appointment.Cancel(u *User) result 有

我试图应用一些DDD概念,我只是想知道什么更有意义:实体调用自己的方法,还是用户(参与者)调用自己的方法

例如,假设我们有一个约会实体。 只有当用户是该约会的所有者时,才能取消该约会(因此我们需要检查用户是否具有适当的权限,然后才能允许该操作)。我们可以采用以下两种方法之一:

pseudocode

// method #1
User.Cancel(a *Appointment) result

// method #2
Appointment.Cancel(u *User) result
有边界的上下文是“约会”,但对于用户来说,调用实体上的行为似乎比调用实体上的行为更有意义。
哪种方法更好,为什么更好?

首先,您需要确定什么是
聚合根(
AR
)、
用户
约会
。为了确定您应该检查必须保护的业务不变量,您应该了解什么是事务边界。有一篇很好的文章。
AR
是用于访问其所有子/嵌套实体的实体

因此,将有一个
AR
和一个子实体(设计中的另一个实体)或两个
AR
,具体取决于您的设计

然后,通过仅指定其他图元的ID而不是孔对象,在聚合上访问该命令方法

Appointment.Cancel(uId *UserID) 

现在,权限检查通常是一种不属于聚合的行为。该验证在调用该方法之前完成。骨料设计不应仅受此许可事项的影响。例如,秘书也可以取消约会,而不仅仅是参与者。权限检查在另一个
有界上下文中

据我所知,从您的领域来看,约会应该是一个
AR
,您的代码应该如下所示:

Appointment.Cancel(byWhom *UserID) 

最后一件事,如果您遵循该模式,则该方法不会返回任何内容。

谢谢您的回答。一切都很清楚,除非你说权限检查不属于聚合。我想这就是聚合的作用——封装领域知识和强制执行不变量。举个例子,约会
AR
不应该知道秘书域对象可以做什么和不能做什么吗?授权是一个交叉关注点,因此是一个通用子域。在Eric Evans的DDD书中,在实现DDD的书中,以及在所有其他来源中,这是作为另一个BC实现的。您可以在这里阅读更多内容:或者在谷歌上搜索“权限检查ddd”
Appointment.Cancel(byWhom *UserID)