一、引子

不知今年吹了什么风,忽然DDD领域驱动设计进入大家视野。该思想源于2003年 Eric Evans编写的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法。刚好公司领导强力推荐这个,抱着学习的心态,耗时5个月,体验了一把:“DDD从入门到弃坑”。

二、思想

学习网站:https://www.jdon.com/ddd.html

服务器后端发展三个阶段:

  1. 面向过程脚本:初始简单,业务复杂后,维护难度指数上升。-->基本不为主流使用
  2. 面向数据库表:初始难度中,业务复杂后,维护难度延迟后再指数上升。--->目前市面上主流
  3. 面向业务模型:DDD+SOA微服务的事件驱动的CQRS读写分离架构:应付复杂业务逻辑,以聚合模型替代数据表模型,以并发的事件驱动替代串联的消息驱动。真正实现以业务实体为核心的灵活拓展。初始难度高,业务复杂后,维护难度线性上升(已很不错)

  DDD革命性在于:领域模型准确反映了业务语言,而传统微服务数据对象除了简单setter/getter方法外,没有任何业务方法,即失血模型,那么DDD领域模型就是充血模型

三、落地

3.1 领域模型设计

以渠道中心(一个微服务)作为例子来做领域模型设计,核心就是设计2个图,一个是战略设计图(宏观)  ,一个是战术设计图(细节)。

1.领域战略设计图

战略设计图是从一个限界上下文的角度出发去分析业务场景。主要是宏观上的核心域、子域、实体关系图。demo如下图:

2.领域战术设计图

战术设计图是从一个限界上下文的角度出发去分析业务场景。细化到核心业务字段、领域实体、值对象、领域服务、领域事件等等。基本上这个图画完,代码已经知道怎么写了。demo如下图:

3.2 技术实现

整体项目框架分层图如下所示:

如上图,4层典型DDD分层结构,

1.展现层:controller层。无业务逻辑

2.应用服务层:此层可以包含查询逻辑,但核心业务逻辑必须下沉到领域层。

3.领域服务层:业务在这里组装。仓储(资源库)接口在此层定义。

4.基础设施层:仓储(资源库)实现层+PO持久化层。

注:

1.简单查询不涉及业务,是可以直接从应用层直接穿透到PO查询,不需要经过domain层。如下图所示,DDD本身是不限制非业务类操作跨层调用的。

2.DTO是不能存在于domain层的,DDD设计不认为DTO是业务对象,entity才是。或者传值简单数据类型也是可以的。

3.2.1 服务调用问题

1.域内调用

领域内调用,随便调用,丝般顺滑。至于实现,可以由一个核心域的仓储实现层(第四层)去实现多个Repository接口。(比如这里A是核心域的实体名,B是支撑域、通用域等)

2.跨域调用

跨域分为

  • 1.同上下文跨域:ACL层->Adapter适配器层→调用其它域的repository。--->不得已才使用,不推荐使用。
  • 推荐:1.使用领域事件 eventbus来做解耦(nest-eventbus使用

    2.考虑是否有可能合并为一个领域.

  • 2.跨上下文(肯定跨域):ACL层->Adapter适配器层->feign调用

3.2.2 包结构

包结构如下:

展开包结构如下:

展现层:Controller,仅做接口的入口定义和编排转发,不做任何的业务处理;

应用服务层:application,负责接口参数DTO的简单校验,以及DTO和实体值对象的数据转换,对于简单的业务,也可以在应用层加载实体直接执行实体行为方法;

领域层:

  • 模型:根据领域模型分析领域内各实体、聚合、聚合根、值对象等,这些对象在*.domain.model定义,实体内的行为方法只负责维护实体自身的生命周期和状态;
  • 行为:领域内各实体、聚合、聚合根等,会有相应的行为,在*.domain.model包下定义行为方法;
  • 领域服务:领域提供的接口服务,需要定义在*.domain.service包下,业务相关的前置业务判断、多个实体或值对象的行为逻辑处理等,都在领域服务中实现,需要注意的是并不是每个实体都有一个对应的领域服务,但是依赖多个实体的行为方法,最好根据这个业务模块是建立一个领域服务;
  • 仓储:领域服务或上层应用服务需要使用到的基础设施层,包括DB、Feign调用等,定义在*.domain.repository下,在*.infrastructure.repository下实现;

适配层:在acl包下的feign定义依赖外部的接口,并在acl的adapter包编写转换,由仓储层操作实体时调用;

持久层:与常用DAO定义一致,由仓储层操作实体时调用。

2)技术架构

目前业内没有标杆,这个就不多介绍,因为我现在使用的架构也不够完善,就不献丑了。

四、总结

DDD可以尝试,但不建议主流业务硬上。建议浅尝即止。(据我所知,业内连阿里巴巴都不敢上。)

DDD领域驱动设计落地实践(十分钟看完,半小时落地)的更多相关文章

  1. DDD领域驱动设计和实践(转载)

    -->目录导航 一. DDD领域驱动设计介绍 1. 什么是领域驱动设计(DDD) 2. 领域驱动设计的特点 3. 如果不使用DDD? 4. 领域驱动设计的分层架构和构成要素 5. 事务脚本和领域 ...

  2. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(3)

    上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDbContext 的实践(2)> 这篇文章主要是对 DDD.Sample 框架增加 Transa ...

  3. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(2)

    上一篇:<DDD 领域驱动设计-谈谈 Repository.IUnitOfWork 和 IDbContext 的实践(1)> 阅读目录: 抽离 IRepository 并改造 Reposi ...

  4. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(1)

    好久没写 DDD 领域驱动设计相关的文章了,嘎嘎!!! 这几天在开发一个新的项目,虽然不是基于领域驱动设计的,但我想把 DDD 架构设计的一些东西运用在上面,但发现了很多问题,这些在之前的短消息项目中 ...

  5. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(转)

    http://www.cnblogs.com/xishuai/p/ddd-repository-iunitofwork-and-idbcontext.html 好久没写 DDD 领域驱动设计相关的文章 ...

  6. 浅谈我对DDD领域驱动设计的理解

    从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能够在线上也能销售自己的产品 ...

  7. (转载)浅谈我对DDD领域驱动设计的理解

    原文地址:http://www.cnblogs.com/netfocus/p/5548025.html 从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来 ...

  8. DDD领域驱动设计的理解

    DDD领域驱动设计的理解 从遇到问题开始 当人们要做一个软件系统时,一般总是因为遇到了什么问题,然后希望通过一个软件系统来解决. 比如,我是一家企业,然后我觉得我现在线下销售自己的产品还不够,我希望能 ...

  9. 关于DDD领域驱动设计的理论知识收集汇总

    原文:关于DDD领域驱动设计的理论知识收集汇总 最近一直在学习领域驱动设计(DDD)的理论知识,从网上搜集了一些个人认为比较有价值的东西,贴出来和大家分享一下: 我一直觉得不要盲目相信权威,比如不能一 ...

随机推荐

  1. JAVA垃圾回收分代处理思想

    原文链接:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/JVM.html JVM分代垃圾回收策略的基础概念 JVM分代垃圾回收策略的基础概念 ...

  2. 寻找最短路径Dijkstra算法

    1 /** 2 * 1.对于T中的每个顶点u,找到u的具有最小权重的连接边.所有到u的连接边都存储在queues.get(u)中.queues.get(u).peek()返回拥有最小权值 3 * 的连 ...

  3. 刷题-力扣-1738. 找出第 K 大的异或坐标值

    1738. 找出第 K 大的异或坐标值 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-kth-largest-xor-co ...

  4. Python之struct模块

    面对网络协议,在组包拆包时,python提供了struct模块,它可以帮助我们在python值和C语言的结构体之间相互转换,下面一起来了解struct的具体用法. 假设,我们的网络协议为消息id(un ...

  5. 对 RESTful 的理解

    REST 全称 Representation State Transfor (资源表现层状态改变) 实际上是指客户端通过http/https协议手段来改变URI的状态转化,达到请求不同的资源的目的. ...

  6. Identity用户管理入门六(判断是否登录)

    目前用户管理的增删改查及登录功能已经全部实现,但存在一个问题,登录后要取消登录按钮显示退出按钮,未登录应该有注册按钮,现实现过程如下 一.Startup.cs中增加服务 app.UseAuthenti ...

  7. java版gRPC实战之五:双向流

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  8. java.net.NoRouteToHostException: Cannot assign requested address

    今天压力测试时, 刚开始出现了很多异常, 都是 java.net.NoRouteToHostException: Cannot assign requested address.  经网上查资料, 是 ...

  9. Python新手的奇技淫巧,掌握在手的充实感

    以下是我长久以来收集的一些Python实用技巧和工具,希望能对刚学习Python的新手有所帮助.  1.交换变量 x = 6 y = 5 x, y = y, x print x >>> ...

  10. PHP垃圾回收机制的一些浅薄理解

    相信只要入门学习过一点开发的同学都知道,不管任何编程语言,一个变量都会保存在内存中.其实,我们这些开发者就是在来回不停地操纵内存,相应地,我们如果一直增加新的变量,内存就会一直增加,如果没有一个好的机 ...