自我理解的洋葱模型
前言
简单说自己理解的洋葱模型。
正文
先来看一个洋葱模型:
这个是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 基本上做两件事:
- 单纯查询数据,当需要查询数据的时候,因为这不涉及到领域业务。
有人就会问了,为什么查询不涉及领域业务呢? 因为查询没有任何修改,本质上是对数据库的查询即可,不涉及到任务业务。
- 为领域层提供基本数据校验和数据查询
基本数据校验:
比如说,需要修改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挂钩,那是另外的事情。
结
简单的自我理解