【问题标题】:DDD How to design services/aggregate roots involving related entitiesDDD 如何设计涉及相关实体的服务/聚合根
【发布时间】:2018-12-01 18:24:18
【问题描述】:

我正在构建一个邀请系统,其中管理员只能邀请

  • 尚未被邀请的用户
  • 尚未加入系统的用户(=已经是成员)

此流程涉及两个实体 InvitationUser

  • 删除用户不应删除他已发送的邀请
  • 更新用户的名字不应更新他的所有邀请

这似乎表明应该将InvitationsUser 添加到两个单独的聚合中。

那么实现上述逻辑的唯一方法就是使用像IInvitationService这样的域服务。 我说的对吗?

这个接口可以有两种方法:

public interface IInvitationService
{
    Task<Result> Create(Invitation invitation, CancellationToken token);
    Task<Result> Delete(Invitation invitation, CancellationToken token);
}

最后,如果我采用服务方式,我将有两种可能的“方式”来创建邀请。

IInvitationRepository.Create() 
IInvitationService.Create()

你不觉得这很混乱吗?

【问题讨论】:

标签: design-patterns domain-driven-design repository-pattern software-design aggregateroot


【解决方案1】:

那么实现上述逻辑的唯一方法就是使用像 IInvitationService 这样的域服务。我说的对吗?

这里似乎出了点问题。总之, 并不意味着我们放弃了面向对象设计的原则。

逻辑通常在发生变化的聚合根中实现。引入聚合模式的部分目的是为了更容易找到负责进行更改的代码——而不是将相同的代码分散在您的模型中,您只需考虑状态更改发生的位置并知道在哪里查找代码。

聚合根本身只知道自己的状态 - 执行更改所需的任何其他信息都作为参数传递给它。

因此,我通常不会期望您到目前为止所描述的模型部分需要“域服务”。

域服务可能发挥作用的情况是,对一个聚合的更改取决于不同聚合的最近状态。例如,如果对“邀请”的特定更改取决于“用户”的当前状态,那么您可以将负责计算更改的域服务传递给邀请方法,该域服务可以访问用户状态的缓存副本。

至于创建...创建模式是奇怪的Udi Dahan's post 是一个很好的起点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-05
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 2022-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多