1. 目录结构

- application    // 应用层
| - assembler      // 用于Entity和DTO转换
| - dto              // 存放DTO对象,DTO作为service的入参
| - - command        // 命令入参,如:add、update、edit、delete
| - - event          // 事件入参,如:addEvent、updateEvent
| - - query          // 查询入参,如:detailQuery、treeQuery
| - - result         // 返回结果,如:addResult、queryResult
| - event          // 事件
| - - listener       // 事件监听器
| - external
| - - impl           // 外部依赖实现
| - service        // 业务服务服务
| - - impl           // 服务实现
- domain         // 领域层
| - converter      // 用于Entity和DO转换
| - entity         // 领域实体类,代表一个有状态的具体的事物
| - external       // 外部依赖
| - repository     // 仓库,用于处理业务语言描述的持久化操作
| - service        // 领域服务
| - types          // 领域原语
- infrastructure // 基础层
| - config         // 配置
| - constant       // 常量
| - enums          // 枚举
| - mapper         // 数据库操作
| - persistence    // 持久化对象
| - util           // 工具类
- interfaces     // 接口层
| - web            // 网页API
| - - rest           // rest接口
| - - ws             // webservice接口
| - mobile         // 移动端API

2. 目录说明

2.1 基础层

对于应用来说,数据库像是硬件,选择了一个数据库后基本就不会变了。而DAO就像是固件,会有改动但改动不大,改动频率也低。

基础层就是一个存放固件的地方,可以将配置、常量、DAO等不经常变化的代码放在这一层。

2.2 领域层

将Data Access层做抽象,降低业务代码对数据库的直接依赖,抽象后放在repository中,其中的方法名称使用save、edit等业务语言代替,而不是insert、update等偏底层的描述。

repository 总是接收实体对象或ID作为参数,并且总是返回实体对象或不返回(void)。

领域服务(Domain Service)用于封装多对象逻辑,被封装的逻辑应该是一体的。

领域原语(Domain Primitives)是一个在特定领域里,拥有精准定义的、可自我验证的、拥有行为的值对象(Value Object),它可以让对象的结构、方法的参数更加清晰。

2.3 应用层

应用服务(application service)用于接收和编排系统服务,如:校验、赋值、保存、通知这样的流程编排。

应用服务应是没有分支流程的,也就是不会有很多if-else(校验的抛错不算),这样可以保证流程的清晰。如:有一个单据需要保存,而不同的单据需要不同的方法保存,且在保存之前还需要进行其他处理,则可以创建帮助类(helper)类来处理。

应用服务永远使用CQE(command、query、event)作为入参,result作为出参,且不同用途的CQE就选内容大致一样,也需要分多个使用,如addCommand、editCommand,需要分开。

  • command太长了一般缩写为cmd,如:UserAddCmd
  • event与spring的事件结尾一样,所以用E代替,如:UserAddE
  • 当然你都简写为C、Q、E、R也可以

2.4 接口层

接口层用于对外提供服务,将web端和移动端的接口分开,并做http服务和webservice服务的区分。

3. 参考:

阿里技术专家详解DD

  1. DDD系列 第一讲:Domain Primitive
  2. DDD系列 第二讲:应用架构
  3. DDD系列 第三讲:Repository模式
  4. DDD系列 第四讲:领域层设计规范
  5. DDD系列 第五讲:如何避免写流水账代码