自我理解的洋葱模型

前言

简单说自己理解的洋葱模型。

正文

先来看一个洋葱模型:

这个是ddd的洋葱模型。

我们看到最里面的是domain model。

为什么里面是domain model呢? 领域模型

domain model 是做什么的,是实现我们业务逻辑模型的,这个重中之重。

然后看domain services 是什么呢?

当涉及到多个domain model的时候,那么就需要domainservice 进行关联。

这里一个domain model 就是一个聚合根。

那么也就是domain model 和 domainservice 实现了我们的核心业务,也就是domain层。

实际上,我们的一个业务例子,就应该调用一个domain model 或者 domainservices 方法,而不是调用多个。

因为domain层就已经是核心领域逻辑业务,就是已经实现了领域业务逻辑的,组装本身也是业务逻辑,所以不应该放在上层。

然后继续往上看,为啥上面有一个application service呢?理论上domain层就已经实现了业务逻辑了。

application service 是对数据的组装与校验

application service 基本上做两件事:

  1. 单纯查询数据,当需要查询数据的时候,因为这不涉及到领域业务。

有人就会问了,为什么查询不涉及领域业务呢? 因为查询没有任何修改,本质上是对数据库的查询即可,不涉及到任务业务。

  1. 为领域层提供基本数据校验和数据查询

基本数据校验:

比如说,需要修改a用户的姓名,那么application service层,要做的事情就是查出用户a,校验用户a是否存在,如果不存在就抛出业务异常

数据查询:

比如说,领域层有一个需要修改用户email的方法:

void EditEmail(string email, string code)
{
   if(Code == code)
   {
      Email = email;
   }else
   {
     throw new Exception();
   }
}

需要传入email和code,code 是为了校验。

那么可能application service 方法是这样的。

void EditEmail(string email)
{
    1. 获取到code
    2. 调用领域层EditEmail方法
}

这上面只是一个假设哈,可能存在需要通过一些去其他服务获取信息的情况。

有人就会疑惑了,也是一个初学者的疑惑。

比如说,业务例子是这样的,修改完email后,需要更新领域B的字段C,这个时候b领域在另外一个B服务中。

是在application service 中这样写呢?

void EditEmail(string email)
{
    1. 获取到code
    2. 调用领域层EditEmail方法
    3. 调用服务B的更新字段C
}

还是在domain层:

void EditEmail(string email, string code)
{
   if(Code == code)
   {
      Email = email;
      // 调用服务B的更新字段C
   }else
   {
     throw new Exception();
   }
}

这里应该是在domain层实现,因为这本事就是其中的一个业务逻辑,涉及到修改,保持一致性和业务完整性。

是否放在domain层就看是否是该领域的业务逻辑。

在外圈就是具体实现了,比如具体实现的services,DB,Jobs 等。

application service 也只是数据的组装和校验而已,没有具体实现的,真正实现就在infrastruction。

差不多由这几层就组成了一个application了。

然后再外圈就是kibana等外部依赖服务了。

这里面实现的其实就是一个控制反转。

就是业务核心逻辑在最高层,而具体实现在低层去依赖最高层,而不是最高层去依赖低层。

为什么要这么做呢?因为我们做项目的目的就是为了去解决业务,业务是核心逻辑。

当需要替换底层的时候,就可以马上进行替换,而让核心逻辑不需要改变。

当核心逻辑需要改变的时候,而又不需要关心底层逻辑,因为高层不依赖低层。

然后最重要的一点就是洋葱模型就是洋葱模型,不要跟什么微服务,cqrs,eventbus挂钩,那是另外的事情。

简单的自我理解