DDD分层架构规范

分层架构图

简述

  1. Controller层:接口层,负责对前端展示的路由和适配;如果需要的话,消费事件和发送消息通知等也可以放在这里;
  2. Application层:主要负责获取输入,组装上下文,参数校验,调用领域层做业务处理
  3. Domain层:领域是应用的核心,主要是封装了核心业务逻辑,通过领域服务(Domain Service)、领域对象(Entity)的方法对App层提供业务实体和业务逻辑计算;
  4. Infrastructure层:主要负责技术细节问题的处理,比如数据库的CRUD、搜索引擎、文件系统、分布式服务的RPC等;

分层说明

  • APP层采用CQE模型,查询和命令分离
  • AppService调用实体和IRepo进行编排实现简单业务,通过调用DomainService实现复杂业务场景
  • AppService和DomainService均为无状态服务
  • App只允许调用仓储以及实体自带方法,不允许写任何方法,避免出现AppService过大的情况
  • DomainService封装所有跨实体的业务逻辑
  • 为避免出现AppService之间或者Domainservice之间相互调用,抽取出两者公共部分为一个Helper

聚合根和实体

  • 按聚合根分包,和包名一样的实体为聚合根
  • 可以识别的聚合根就写成聚合根,否则做成实体
  • 聚合根的一致性由自己保障
  • 跨实体的操作放到领域服务中

领域对象实体为充血模型,为一般业务对象,具备业务属性和业务行为

  • 实体都有自己的唯一标识通常
  • 实体可以不和表一一对应,通常操作单个表,可以操作多表

领域服务

某个操作过程或转换过程不是实体的职责时,我们便应该将该操作放在一个单独的接口中,即领域服务。

  • 用于实现某个领域的任务,不适合放在实体对象上时,就放在领域服务上
  • 放在实体的静态方法上有悖DDD
  • 避免在实体中调用资源库,数据通过AppService调用Repo传入
  • 如果有复杂逻辑,其中间的状态依赖前面步骤结果查询数据库作为后续逻辑的输入,通过把Repo传入到Domainservice的方式达到无状态效果

传输对象

  • DTO:接受Controller层发来的请求,返回结果
  • Entity :将DTO转换为要操作的领域层对象

无状态

  • 一次请求所需的全部信息,要么都包含在这个请求里,要么可以从外部获取到(比如说数据库),服务本身不存储任何信息
  • 有状态服务(stateful service)则相反,它会在自身保存一些数据,先后的请求是有关联的
  • 无状态服务的优势在于可以很方便地水平伸缩