DDD工程结构说明

  |   0 评论   |   0 浏览

文档

本工程采用DDD的架构风格,经过组内DDD实践的沉淀形成的工程规范 DDD实践的参考文档详见:

DDD实践参考文档

工程结构:


--client/
|-- src
    |----|-- main
    |----|----|-- java
    |----|----|----|-- com.sankuai.crayfish.xxxx
    |----|----|----|----|-- service -- thrift服务
    |----|----|----|----|-- model -- thrift对象定义
--server/
    |-- deploy
    |-- src
    |----|-- main
    |----|----|-- java
    |----|----|----|-- com.sankuai.crayfish.xxxx
    |----|----|----|-- application -- 应用层
    |----|----|----|----|-- service -- 应用服务
    |----|----|----|----|-- factory -- 对象转换工程(非必须)
    |----|----|----|----|-- validator -- 应用层参数校验(非必须)
    |----|----|----|-- domain -- 领域层
    |----|----|----|----|-- aggragate -- 聚合层
    |----|----|----|----|-- convertor -- 对象转换(非必须)
    |----|----|----|----|-- entity -- 实体
    |----|----|----|----|-- event -- 领域事件(非必须)
    |----|----|----|----|-- repository -- 资源库行为
    |----|----|----|----|-- service -- 领域服务
    |----|----|----|----|-- valueobj -- 值对象
    |----|----|----|---| remote -- 远程调用接口申明(Interface)
    |----|----|----|-- infrustructure -- 基础设施层
    |----|----|----|----|-- annotation -- 注解
    |----|----|----|----|-- cache -- 缓存配置
    |----|----|----|----|-- common -- 公共目录
    |----|----|----|----|-- config -- 通用配置
    |----|----|----|----|-- mafka -- mq配置
    |----|----|----|----|-- http -- http接口
    |----|----|----|----|-- thrift -- thrift接口
    |----|----|----|----|-- repository -- 资源库
    |----|----|----|----|----|-- impl -- 资源库实现
    |----|----|----|----|----|----|-- convertor -- 对象转换(非必须)
    |----|----|----|----|----|-- persist -- 持久化
    |----|----|----|----|----|----|-- mapper -- 数据库mapper
    |----|----|----|----|----|----|-- model -- DO对象  
    |----|----|----|----|-- remote -- 远程调用(实现)
    |----|----|----|----|----| impl -- 远程调用(接口实现)
    |----|----|----|----|----| model -- 远程调用(thrift层对象申明)
    |----|----|----|----|-- util -- 对象转换
    |----|----|----|-- Application.java(启动类)
    |----|----|-- resources -- 资源
    |----|----|----|-- mabatis -- db配置
    |----|----|----|-- spring -- spring配置
    |----|----|----|-- application.properties -- 配置文件
    |----|----|-- profiles

下面针对每层进行说明:

应用层

应用服务是领域模型的直接客户,应用层要尽量简单,不包含业务规则或者知识,而只为下一层(指领域层)中的领域对象协调任务,分配工作,使它们互相协作。

领域层提供了细粒度的领域模型对象,不利于它的客户端调用。因此,“基于 KISS(Keep It Simple and Stupid)原则或最小知识原则,我们希望调用者了解的知识越少越好,调用变得越简单越好,这就需要引入一个间接的层来封装。这就是应用层存在的主要意义

目录说明

【service】放置应用层服务

【factory】放置应用层对象转换的工厂,非必须,有些情况下不需要对象转换的工厂

【validator】应用层参数校验逻辑的放置目录,`非必须,有些情况下不需要参数校验,参数校验应该遵循约定,具体参考实践文档

开发规约:

1.【强制】禁止在应用层写任何领域逻辑,仅负责协调领域模型对象,通过它们的领域能力来组合完成一个完整的应用目标

2.【强制】与横切关注点相关的内容应该放在应用层

3.【强制】thrift接口参数校验属于横切关注点,应该放在应用服务来做

领域层

DDD架构风格的核心层,领域逻辑的主要载体

aggregate 聚合

Eric Evans 阐释了何谓聚合模式:“将实体和值对象划分为聚合并围绕着聚合定义边界。选择一个实体作为每个聚合的根,并允许外部对象仅能持有聚合根的引用。作为一个整体来定义聚合的属性和不变量(Invariants),并将执行职责(Enforcement Responsibility)赋予聚合根或指定的框架机制。”

entity 实体

实体有自己的生命周期,他的生命周期从属于聚合根。能够以主体类型的形式表达领域逻辑中具有个性特征的概念,而这个主体的状态在相当长一段时间内会持续地变化,因此需要有一个身份标识(Identity) 来标记它。

一个典型的实体应该具备三个要素:

  • 身份标识
  • 属性
  • 领域行为

规约

1.【强制】实体对象的命名以Entity结尾。比如UserEntity、CompanyEntity

valueobj 值对象

值类型用于度量和描述事物,是否拥有唯一的身份标识才是实体与值对象的根本区别

规约

1.【强制】值对象的命名规则为 name + Value

event 领域事件

发生在领域中的一些事件,将领域中所发生的活动建模成一系列的离散事件,每个事件都用领域对象来表示,领域事件是领域模型的组成部分,表示领域中过去发生的事情。

remote 远程调用

领域层remote只放置rpc接口的申明,具体实现放在基础设施层

service 领域服务

领域服务(Domain Service)代表了在名词世界(面向对象)中对动词的封装(接口),它封装了领域行为。表示一个无状态的操作

前提在于,这一领域行为在实体或值对象中找不到容身之处。换言之,当我们针对领域行为建模时,需要优先考虑使用值对象和实体来封装领域行为,只有确定无法寻觅到合适的对象来承担时,才将该行为建模为领域服务的方法。

repository 资源库

只定义Interface,代表了一种行为,实现放在基础设施层

convertor 转换器

非必须,如果需要这样的逻辑,放在转换器里

基础设施层

基础设施的职责是为应用程序的其他部分提供技术支持。

Http http接口

Thrift thrift接口

Config 通用配置

Repository 资源库

Remote Rpc调用实现

--|【impl】 Rpc调用实现
--|【model】Rpc调用需要的对象
--|【impl】领域层定义资源库行为的实现
--|---|--【convertor】领域层对象和持久层对象的转换服务 -- 非必须
--|【persist】持久层mapper、DO

Cache 缓存配置

Annotation 注解

Mafka mq配置


标题:DDD工程结构说明
作者:guobing
地址:http://www.guobingwei.tech/articles/2020/11/07/1604685041050.html