整洁架构图

依赖方向朝内,每个环可以依赖它本身这一层及其所有内部的层,但不能依赖它外部的层

  • Entities
用来放实体、值对象、聚合等领域模型的
业务逻辑都应该尽量内聚在这一层
这一层是最纯净的,不需要依赖任何其它东西
  • Use Cases
用于协调进出Entities层的数据流
通过调用和编排领域模型来实现用例
在DDD中,这一层通常是Application Service层
是很薄的一层,只用来做一些比较简单的事情
  • Interface Adapters
这一层叫“接口适配层”,它其实是主要用来与外部进行适配的
比如Web请求进来的Controllers(写)和Presenters(读)
这一层会将User Cases或Entities层需要的数据结构与外层的数据结构做一个转换
比如操作数据库、调用第三方接口等
  • Frameworks and Drivers
这一层主要是框架和驱动层,比如数据库驱动、WEB框架、UI等
日常编码中很少会在这一层编写代码
  • 跨越边界和依赖反转
业务流程通常是先从controller进来,调用Use Cases层
但有时候Use Cases层需要调用presenter
如果直接调用,就破坏了“向内依赖规则”
这个时候可以用“依赖反转”来做

1、在Use Cases层定义两种抽象类或者接口:Use Case Input Port和Use Case Output Port2、Use Case Interactor去实现了Use Case Input Port3、Presenter去实现了Use Case Output Port这样Use Cases层就不用依赖外部的层了同样的道理,也可用于对数据库、第三方接口等的交互场景

六边形架构

内部是整洁架构的模式,并且和DDD很好的结合了起来a、领域层:最中间的是领域模型+领域服务
b、应用层:也包含两个环 里面是App Services,外面是C/Q处理器、事件监听器
c、大红色轮廓包起来的Application Core
这一层定义了很多接口(也可以说是端口)
比如持久化、第三方服务、搜索、CQ总线、事件总线等等
也接收处理命令和查询

DDD战术模式问题的思考

  • 何时需要领域服务
当只使用领域模型做不到的时候,就需要领域服务
什么情况下领域模型做不到,领域服务就做得到?
一个很常见的场景是创建模型的时候有业务逻辑
虽然创建模型通常是放在Factory里面,但Factory里面并不适合放业务逻辑
而这个时候领域模型还没有创建,自然就只能放在领域服务里面了
  • 应用层需要查询其它数据如何处理
不止是需要当前这个聚合根的数据,可能还需要其它的数据
这个读取操作当然不可能放到领域层去做,通常把它放在应用层
但应用层通常是一个聚合根对应一个ApplicationService
正常的流程是调用Repository接口获取一个领域模型对象
然后对它进行操作,再保存回数据库那如果需要获取其它数据怎么办呢?尤其是可能与当前领域模型无关的数据,比如“最近评论时间”通过依赖反转的方式 实现一个Use Case Output Port抽象类即可 具体原理详见'跨越边界和依赖反转'
  • 领域事件何时发送和接受
个人认为在领域层创建比较好
因为创建领域事件其实也算是一种业务逻辑
并且只是创建一个领域事件的话,不会依赖任何外部的东西,放在领域层没有什么问题那什么时候发送领域事件呢?按照整洁架构的规则,不应该在领域层发送
因为事件总线(或者事件发送器的实现)在最外层
如果在领域层发送,虽然有依赖倒置,但感觉也跨越太多层次了
不是一个好的实践
  • 跨聚合根的事务
跨聚合根应该使用事件通信,但事件的实现方式有多种
如果是异步,那就保证不了强一致的事务
只能用一些技术手段去尽量保证最终一致
  • 保证架构如何不被腐化
推荐使用maven/gradle的模块化
因为模块之间是有依赖关系的
只要不去改依赖的配置,就永远是单向依赖的
具体来说,可以把整洁架构上面的层级分成一个个模块
然后在配置文件里面定义它们的依赖关系
比如应用层模块,依赖领域层模块
接口和适配层模块依赖应用层模块和领域层模块
  • 定义合适的聚合根
定义一个聚合根应该很简单,根据业务来就是了
比如用户、订单、商品、库存等等
但有时候我们很容易把聚合根定义得很大聚合根太大可能会有问题,比如代码过多、测试用例过多、性能不好等等只是要找到合适的“借口”,要拆得有理有据

截止目前原理简介已经介绍过了 但如果没有具体项目实践的话 相信还不足以深刻理解 接下来进入项目实践环节

DDD项目实践

  • 完整代码地址
https://gitee.com/pingfanrenbiji/ddd

项目结构

  • interface-adapter 接口适配层(适配dubbo、rest接口等协议)

  • application 应用层(实现用例的地方,eg:电商场景里的用户下单是个用例)

  • domain 领域层(写领域逻辑的地方,eg:电商场景里的用户下单包含订单逻辑、商品逻辑、以及优惠逻辑等)

  • infrastructure 基础层(放Cache、MQ框架、数据库持久实现等的地方)

采用依赖倒置的依赖关系

数据流交互过程概览

具体模块介绍

具体代码请自行下载项目查看 这里仅点到为止

领域模块

  • 领域服务

定义一个方法 参数为具体的请求指令 比如当前方法接收生成商品指令
  • 具体事件对象定义

  • 领域模型定义

  • 该领域模型行为定义

  • 该领域模型存储接口定义

这里仅定义接口 具体实现在application模块

application模块

application接口调用命令总线

core 模块

命令总线在core模块

  • 分发命令
  • 注册命令处理器
  • 注册命令拦截器
注册处理器
  • 注册命令处理器
  • 注册事件处理器
  • 注册命令拦截器处理器

方式1

如果你的项目是spring项目 则需要在配置文件中注入

方式2

如果你的项目是springboot项目

ddd-spring-boot-starter jar包会读取spring.provides获取加载bean的来源

ddd-spring-boot-autoconfigure 定义好要初始化的bean

命令总线初始化

加载所有的命令相关的bean注册到命令总线中

事件总线初始化

上文收到application调用命令总线转发接口

这里是模版设计模式
具体实现类在aplication模块中实现

调用core模块的事件总线方法

  • 同步发布事件
  • 异步发布事件
  • 注册事件

获取线程池中的一个线程去启动事件执行器

事件执行器

抽线类实现该接口

该事件执行器的抽象方法的具体实现在application 模块中

后记

结合原理简介和项目实践 Do you understand DDD?
believe oneself !!!后续会介绍下 隐私计算之隐匿查询

领域驱动DDD原理简介与实践相关推荐

  1. DDD(Domain Driven Design) 领域驱动设计从理论到实践 四

    - 接上 SOA 架构 ​     面向服务架构(Service Oriented Architecture,SOA)对于不同的人来说意思不同.这里梳理一下SOA原则: 服务契约 : 通过契约文档,服 ...

  2. 领域驱动设计之单元测试最佳实践(二)

    领域驱动设计之单元测试最佳实践(一) 介绍完了DDD案例,我们终于可以进入主题了,本方案的测试代码基于Xunit编写,断言组件采用了FluentAssertions,类似的组件还有Shouldly.另 ...

  3. 领域驱动DDD在签到场景落地案例之架构模式(二)

    承接DDD概念初识第二篇,第一篇传送地址:领域驱动DDD在签到场景落地案例之概念初识(一) 本篇文章介绍微服务设计原则,以此为设计思想,然后列举DDD常见架构模式,不同架构方式对比,在工作中根据业务选 ...

  4. 领域驱动设计-原理心得篇

    "最初我给本文起的标题是<领域驱动设计-理论入门篇>,但是文中掺杂了太多的个人理解,入门篇就显得太官方了,为了避免错误的理解把读者带偏,所以改成<领域驱动设计-理论心得篇& ...

  5. nvme通用驱动_对领域驱动设计的理解与实践

    领域驱动设计(Domain-Driven-Design)是一种针对大型复杂系统的领域建模与分析方法论. 2003 年,Eric Evans 发布<Domain-Driven Design: Ta ...

  6. 对领域驱动设计的理解与实践

    前言 领域驱动设计(Domain-Driven-Design)是一种针对大型复杂系统的领域建模与分析方法论.2003 年,Eric Evans 发布<Domain-Driven Design: ...

  7. 领域驱动设计--京东研发团队实践(六)

    过去几年,通天塔一直处于快速的业务能力建设和架构完善的阶段,以应对不断增长的业务需求和容量.高可用等技术需求,现在通天塔平台已经能满足集团主站的大部分活动.频道搭建和运营能力,主流程的新需求越来越少, ...

  8. 领域驱动DDD在签到场景落地案例之概念初识(一)

    领域驱动(DDD) 了解领域驱动设计前我们不妨先问自己几个问题: 1. 领域驱动设计是什么? 2. 为什么要用领域领域驱动设计来指导开发软件? 3. 什么样的业务场景更适合领域驱动设计? 领域驱动设计 ...

  9. 领域驱动设计--领域驱动设计到数据建模实践(十)

    ----- 学习笔记 ----- 过去,系统的软件设计是以数据库设计为核心,当需求确定下来以后,团队首先开始进行数据库设计.因为数据库是各个模块唯一的接口,当整个团队将数据库设计确定下来以后,就可以按 ...

最新文章

  1. Android如何防止apk程序被反编译
  2. phpcms V9 相关阅读/相关文章
  3. java网络文章博客抓取系统_java 后端博客系统文章系统——No3
  4. WebView跳转到底部
  5. shell的控制语句
  6. SENET——imageNet冠军解读
  7. mysql 命令类型_mysql 基本命令(3)-数据类型和运算符
  8. 系统学习机器学习之模型诊断与调试
  9. SQL Server 2008 Service Broker
  10. Apache Flink 进阶(二):时间属性深度解析
  11. 在边缘计算大热的背景下,为何Akamai敢说自己就是边缘
  12. 【Oracle】IF EXISTS用法
  13. SSM+Flowplayer实现web项目网页看视频
  14. 美国篮球巨星科比坠机去世 年仅41岁
  15. [python3]读取docx每个段落下的table数据
  16. table总结insertRow、deleteRow
  17. php转换透明ico,php在线生成ico文件的代码_PHP教程
  18. VSCode快速生成HTML基础模板--输入!一键快捷生成--无法自动生成的解决办法
  19. python笔记打卡
  20. Innodb简介及性能调优

热门文章

  1. SpringCache 集成 Redis,这才是优雅的缓存解决方案!
  2. JDK的下载、安装和配置
  3. 聚合中返回source_大数据搜索与可视化分析(9)elasticsearch聚合分析Metric Aggregation...
  4. 【SpringSecurity系列02】SpringSecurity 表单认证逻辑源码解读
  5. 排序学习之---插入排序
  6. 机器视觉产品技术市场需求日益增长
  7. shell脚本 回顾 小练习
  8. ubuntu下chromium 安装flash player
  9. [android] 请求码和结果码的作用
  10. 项目分布式部署那些事(1):ONS消息队列、基于Redis的Session共享,开源共享