领域驱动设计杂谈

86394795 2019-12-31

一、为什么domain和infrastructure会进行依赖倒置:

  1. ddd中domain才是真正的业务核心层,而domain作为业务核心,并不应该写入大量转换代码
  2. 反向思考下,如果domain层依赖infrastructure,Repository组件内是无法引用已有聚合的,这需要在domain层加入大量代码,把我们的entity转为数据层的po对象。
  3. 以订单为例,订单状态枚举,应该是订单域的一个枚举,这个枚举要写在订单域,但实际上基础设施层是使用枚举进行传递的。
  4. 同样的道理,一个子域的本身的功能,写进子域后可能需要对外暴露,正向依赖会导致无法暴露子域功能给基础设施层

二、为什么各层之间会有很多转换器:

  1. 保证每层的纯洁性,各层可以只接受自己指定的入参。
  2. 各层可以根据自己的实际情况,自行定义dto
  3. 便于后续其它层有修改时,给出快速应对

三、仓储组件应该基于什么维度:

  1. 仓储是为每个domain层提供基础数据服务。综合考虑下,仓储最好是基于实体。
  2. 仓储不基于聚合,是因为部分大聚合如果只有一个实体,会导致仓储文件膨胀
  3. 仓储不能基于值对象,值对象一定可以挂在实体上,理论上不存在对外无关联的值对象。
  4. 仓储是不应该基于数据层或rpc的。比如我们订单多个子域都需要调用用户服务获取用户值对象,但实际上用户信息对外基本都是值对象,而值对象是不能作为一个独立仓储给各个子域提供服务的。

四、对于同一个RPC服务,多个子域应该如何调用:

领域驱动设计杂谈

五、零散问题:

  1. 首先对于每个服务,其实有部分uitl类可以开放给其他服务。例如商品服务需要提供出前后端尺码转换,供各处调用。此类uitl包是可以拉出一个独立的common包,供外部调用。但这样一来,会导致一个服务有两个包对外提供服务。
  2. 一些domain层共用的uitl按照现在的分层,其实是每个domain层自己写一次。这里也考虑过抽出一个common包对内提供服务。但这个包一方面会很薄,另一方面后续拆服务,common包还是会拆到各个服务。
  3. 为了解决repository层抛出null后无法在domain层判断的问题,可约定repository不会返回null,转为new Object()的方式

相关推荐