Java架构设计之六步拆解 DDD

目录
  • 引言
  • 项目需求信息
  • DDD落地实践
  • 战略设计
    • 1、业务分析
      • (1)事前准备
      • (2)邀请参会的人
      • (3)业务讨论
    • 2、领域建模
      • (1)领域对象分析
      • (2)构建业务聚合
    • 3、划分边界上下文
  • 战术设计
    • 1、微服务拆分
    • 2、领域分层
    • 3、代码结构
  • 总结

引言

相信通过前面几篇文章的介绍,大家对于 DDD 的相关理论以及实践的套路有了一定的理解,但是理解 DDD 理论和实践手段是一回事,能不能把这些理论知识实际应用到我们实际工作中又是另外一回事,因此本文通过实际的业务分析把之前文章中涉及的理论和手段全部带着大家走一遍,我想通过这种方式,让大家实际的感受下 DDD 落地过程中会遇到哪些问题以及我们应该怎样去解决这些问题。

项目需求信息

这里还是大家比较熟悉的电商场景来进行说明,我想这样大家比较好理解一点。在前段时间双十一,大家被各种购物优惠券的套路整的眼花缭乱,仿佛数学不好,都不配拿到最优惠的价格了。大家都在吐槽,就不能少点套路,买东西直接给我 5 折不就天下太平了吗?我想造成这种现象的原因大概就是中国电商行业的内卷吧,只有通过各种营销活动的堆积,才能让大家话更多的时间去浏览更过的商品,才能获得更好的留客以及交易。好了,跑题了,这些我们先不去关心。那我们今天就用这个折磨人的优惠券的流程作为设计实例来说明整个 DDD 的落地过程吧。优惠券的关键业务流程如下:

(1)当需要进行大促活动的时候,运营同学需要选定对应的商品,创建创建优惠券。

(2)运营同学需要创建营销活动,制定对应的营销活动规则,比如什么满减啊,跨店减啊类似这种折磨人脑细胞的规则,然后关联相应的优惠券,最后提交活动审批。审批通过后,进行营销活动发布。

(3)提交活动审批后,审批进行营销活动审批。

(4)用户在营销页面领取优惠券之后,下单购买商品之后,在付款的时候根据对应的优惠券进行付费金额计算并完成支付。

DDD 落地实践

项目背景信息我们大致了解之后,那么我们就要着手开始通过DDD来进行领域驱动设计的过程了。其实我们学习 DDD 理论以及方法不是最终的目的,而通过它实现实际的业务复杂度治理以及优化微服务设计才是真正的目的。

战略设计

在战略设计阶段,我们最主要的过程大致包括了业务场景分析、领域建模、划分边界上下文三个阶段。实际上战略设计是 DDD 过程中的核心步骤。

1、业务分析

在这个阶段我们所有做的就是进行全面的业务梳理,吧业务中涉及到的所有细节都梳理出来,为后续进行领域建模分析提供足够的、全面的业务输入。经常使用到的业务场景分析方法主要包括用例分析法、事件风暴法以及四色建模法。这里我们使用事件风暴进行业务场景的分析以及梳理。

(1)事前准备

在进行事件风暴之前我们需要进行一些准备,主要包括贴纸、笔以及讨论的会议室,会议室中最好不要有椅子,目的是想让大家都能够站立在一起、全神贯注的去进行业务讨论。

(2)邀请参会的人

会议的参与方主要包括业务、用户、PD、研发、测试、架构师等。

(3)业务讨论

首先确定我们今天需要讨论的业务是什么,目标是什么。像前文所说的那样,本次讨论的业务就是营销活动的优惠券业务,目标就是完成优惠券的业务梳理,确保没有业务方面的理解 gap,在团队中达成业务理解的的一致性。在这个过程中我们需要通过提问的方式来驱动交流。

a、分析业务中的事件,搞清楚事件发生的前因后果,什么意思呢?就是什么动作会导致当前时间的发生,当前这个事件发生后又会导致怎样的后果。这些我们都需要梳理清楚。还有一点需要注意, 我不但要关注正常的业务流程还要关注异常的业务流程。

b、寻找业务逻辑和业务规则,比如我们在提交活动前,需要确定这些优惠券适用哪些人、领取方式是怎样的以及生效事件是怎样的等等,这些都是我们在执行操作之前需要确定的业务规则。

如下图所示,我们将优惠券的业务流程进行了梳理,分别从操作人、事件、命令的方式来描述整个优惠券业务流转的过程。

注:在进行事件风暴过程中,所有的参与人都要全身投入整个过程,放下手机以及电脑,一起参与整个业务梳理过程,只有这样,事件风暴才可能有比较好的效果。

2、领域建模

在前面的事件风暴业务梳理中,我们已经把优惠券业务涉及到的参与者、动作以及事件等都进行了全面的梳理。那么接下来我们就要在此基础之上进行领域建模,这是整个 DDD 的核心。

(1)领域对象分析

如上面所示的事件风暴小黑板中的内容,我们需要在这些梳理出来的内容中找到对应的实体、值对象以及围绕这些的领域事件以及命令操作。根据分析,我们总整个业务过程中提取了优惠券、营销活动、活动审批单、活动规则、审批意见等实体以及值对象以及和这些领域对象相关的命令操作。

(2)构建业务聚合

完成领域对象分析之后,我们需要构建业务聚合。想要构建聚合,那么首先就要在实体中找到聚合根。我们先来回顾下聚合根的特点,聚合根一定是实体,那么它具有全局唯一的标识,另外它是具备生命周期的同时需要专门的模块来进行管理。根据这样的标准,在领域对象中我们发现优惠券、营销活动以及活动审批单是具备聚合根特征的,而营销规则、营销内容等是和营销活动紧密相关的,因此他们构成营销活动聚合关系。优惠券规则、优惠券类型等是和优惠券聚合根紧密相连的,所以他们构成优惠券聚合关系。同理活动审批单也会构成聚合关系。最终我们形成如下的聚合关系。

3、划分边界上下文

在上述步骤中,我们获得了整个业务流程中的所有聚合后,我们需要更具业务语义上下文将具体的聚合划分到对应的上下文中,因此我们可以把优惠券的业务分为优惠券、营销活动以及审批三个限界上下文。

战术设计

在战略设计阶段,我们通过事件风暴法对整体的业务进行了全部的梳理,同时构建了领域模型以及划分了边界下文。那么接下来我们就要将领域模型映射到工程结构以及代码中实现最终的实现落地。另外在这个阶段实际还有很多细节需要明确,那优惠券来说,它包含哪些属性,需要哪些领域服务,哪些需要设计为实体,哪些需要设计为值对象,这些都是需要在战术设计阶段明确下来。

1、微服务拆分

我们根据已经划分的边界上下文,我们可以拆分为优惠券服务、营销活动服务以及审批中心三个微服务,至于用户支付使用这块,还是由原先已存在支付服务来完成,只是在付款核算的时候需要使用到优惠券进行最后的金额计算。

2、领域分层

在领域分层方面,我们还是按照之前文章中所说的分层结构来进行,即 interfaces 层、biz 层、domain 层以及 instructure 层。每层代表的含义之前的文章中已经进行了详细的说明,大家可以翻看前面文章中的介绍,这里不再进行赘述了。

我们以优惠券为例,实际聚合中对象还需要进行进一步的细化。对于优惠券来说它实际上还有如下所示的值对象以及实体来组成实际的优惠券。同时在优惠券我们的梳理的领域服务还包括创建优惠券、查询优惠券以及修改优惠券状态,这些动作实际都应该在领域层通过领域服务的形式完成落地。而对应的 biz 层就相当于业务的编排组合,也就是实际的业务流程的串联。

3、代码结构

当我们把领域对象进行进一步的细化之后,同时把对应的领域服务敲定之后,我们可以把这些分析后的内容映射成工程分层后的代码了。如下图所示,即为优惠券的 domain 层的代码映射。

当然到这里并不意味着结束,其实在后续还有很多工作要做,比如详细设计、编写代码以及功能测试,特别实在详细设计阶段,我们还要涉及很多的细节问题的敲定,比如数据库表的设计、比如使用什么 MQ,用不用缓存,怎么保证缓存和数据库的数据一致性问题,分布式服务有没有分布式事务的问题,应该怎么解决?有没有服务幂等问题,应该怎么解决?这些都是需要在详细设计阶段进行确定的。因此 DDD 就像是框架,通过它把业务映射成为领域对象以及领域服务和领域事件,再把这些领域相关内容再读映射为实际的代码。使得我们的服务更加的逻辑清晰以及扩展性更强,但是分布式的技术实现细节,我们还是需要有对应的解决方案来进行解决。

总结

本文以电商行业的营销活动中的优惠券的发放和使用作为实际案例来阐述 DDD 领域驱动设计落地实践的过程,通过整个过程的梳理,为大家提炼了整个设计过程的精要,相信大家可以按照这样的思路在实际的工作中再结合各自的业务特征应该可以真正完成整个 DDD 的实践。万事开头难,相信只要大家能够亲自去参与或者主导一个 DDD 的落地实践过程,那么对于理解 DDD 这套架构设计方法论又会进入一个新的台阶。在后面的文章中再和大家聊聊落地 DDD 过程中可能会遇到的一些问题以及软件复杂度治理的问题。

真正的大师永远怀着一颗学徒的心 ————————————————

到此这篇关于Java架构设计之六步拆解 DDD的文章就介绍到这了,更多相关Java 拆解 DDD内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java Mybatis架构设计深入了解

    目录 架构设计 Mybatis主要构件 Mybatis缓存 总结: 架构设计 我们可以把Mybatis的功能架构分为三层: 1.API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库.接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理. Mybatis和数据库的交互有两种方式: 使用传统的Mybatis提供API 使用Mapper代理的方式 2.数据处理层:负责具体的SQL查找.SQL解析.SQL执行和执行结果映射处理等.他主要的目的是根据调用的请求完成一次数

  • java开发微服务架构设计消息队列的水有多深

    目录 消息队列的作用 消息队列的设计难题 处理并发和顺序消息 处理重复消息 编写幂等消息处理器 跟踪消息并丢弃重复消息 处理事务性消息 使用数据库表作为消息队列 使用事务日志发布事件 RocketMQ事务消息解决方案 很多人在做架构设计时往往会"过度设计",简单问题复杂化,上来就引一堆中间件,我想大概原因主要有下面两点: 为了秀(学)技术而架构 我们常说技术是为业务服务的,不能为了技术而技术,为了秀技术引入一堆复杂架构这是要不得的. 考虑问题不全面,或者说广度不够,不知道如何简单化 举

  • 浅谈Java开发架构之领域驱动设计DDD落地

    目录 一.前言 二.开发目标 三.服务架构 3.1.应用层{application} 3.2.领域层{domain} 3.3.基础层{infrastructrue} 3.4.接口层{interfaces} 四.开发环境 五.代码示例 六.综上总结 一.前言 整个过程大概是这样的,开发团队和领域专家一起通过 通用语言(Ubiquitous Language)去理解和消化领域知识,从领域知识中提取和划分为一个一个的子领域(核心子域,通用子域,支撑子域),并在子领域上建立模型,再重复以上步骤,这样周而

  • Java 高并发编程之最实用的任务执行架构设计建议收藏

    目录 前言 1.业务架构 2.技术架构 3.物理架构 高并发任务执行架构 需求场景 业务架构设计 技术架构设计 初始设计 演化阶段一 演化阶段二 演化阶段三 代码设计 总结 前言 随着互联网与软件的发展,除了程序员,架构师也是越来越火的职业.他们伴随着项目的整个生命过程,他们更像是传统工业的设计师,将项目当做生命一般细心雕琢. 目前对于项目架构而言,基本都会需要设计的几个架构. 1.业务架构 项目或者产品的市场定位.需求范围.作用场景都是需要在项目启动初期进行系统性分析的.在设计业务架构中,架构

  • Java架构设计之六步拆解 DDD

    目录 引言 项目需求信息 DDD落地实践 战略设计 1.业务分析 (1)事前准备 (2)邀请参会的人 (3)业务讨论 2.领域建模 (1)领域对象分析 (2)构建业务聚合 3.划分边界上下文 战术设计 1.微服务拆分 2.领域分层 3.代码结构 总结 引言 相信通过前面几篇文章的介绍,大家对于 DDD 的相关理论以及实践的套路有了一定的理解,但是理解 DDD 理论和实践手段是一回事,能不能把这些理论知识实际应用到我们实际工作中又是另外一回事,因此本文通过实际的业务分析把之前文章中涉及的理论和手段

  • 一条sql详解MYSQL的架构设计详情

    目录 1 前言 2 应用层 2.1 连接线程处理 3 服务层 3.1 SQL 接口 3.2 SQL解析器 3.3 SQL优化器 3.4 执行器 3.5 查询缓存 4 存储引擎层 4.1 概述 4.2 缓冲池(buffer pool) 4.2.1 数据页.缓存页和脏页 4.2.2 元数据 4.2.3 free链表 4.2.4 flush链表 4.2.5 LRU链表 4.2.6 小结 4.3 undo log 4.4 redo log 5 总结 1 前言 对于一个服务端开发来说 MYSQL 可能是他

  • 解析Tomcat架构原理到架构设计

    目录 一.学习目的 1.1.掌握 Tomcat 架构设计与原理提高内功 1.2.宏观理解一个请求如何与 Spring 联系起来 1.3.提升自己的系统设计能力 二.整体架构设计 2.1.连接器 2.2.封装变与不变 2.3.容器 2.4.请求定位 Servlet 的过程 三.Tomcat 为何打破双亲委派机制 3.1.双亲委派 3.2.Tomcat 热加载 3.3.Tomcat 的类加载器 3.4.Tomcat 类加载器层次 四.整体架构设计解析收获总结 4.1.连接器 4.2.容器 4.3.类

  • 10本Java架构师必读书籍

    Java架构师必读书籍,分享给大家 1.大型网站系统与JAVA中间件实践 本书围绕大型网站和支撑大型网站架构的Java中间件的实践展开介绍. 从分布式系统的知识切入,让读者对分布式系统有基本的了解:然后介绍大型网站随着数据量.访问量增长而发生的架构变迁:接着讲述构建Java中间件的相关知识:之后的几章都是根据笔者的经验来介绍支撑大型网站架构的Java中间件系统的设计和实践.希望读者通过本书可以了解大型网站架构变迁过程中的较为通用的问题和解法,并了解构建支撑大型网站的Java中间件的实践经验. 对

  • 谈一谈jQuery核心架构设计

    jQuery对于大家而言并不陌生,因此关于它是什么以及它的作用,在这里我就不多言了,而本篇文章的目的是想通过对源码简单的分析来讨论 jQuery 的核心架构设计,以及jQuery 是如何利用javascript中的高级特性来构建如此伟大的javascript库. 1 初识jQuery 从核心功能来看,jQuery仅仅做了一件简单而又平凡的事:查询.它的语法如此简洁明了,以致于很多人在不知道javascript是什么的时候就已经会用jQuery了,用一个词形容就是:大道至简. 从设计层面来看,我们

  • 微服务架构设计RocketMQ基础及环境整合

    目录 概述&选型 单机安装配置 双机主从高可用搭建 启动多个NameServer 和 Broker 重要参数说明 可视化管理平台 SpringBoot整合RocketMQ 引入组件rocketmq-spring-boot-starter 依赖 修改application.yml,添加RocketMQ相关配置 编写消息生产者 MessageProduce 编写消息消费者 MessageConsumer 编写单元测试发送消息 测试 概述&选型 消息队列作为高并发系统的核心组件之一,能够帮助业务

  • RocketMQ之NameServer架构设计及启动关闭流程源码分析

    目录 NameServer 1.架构设计 2.核心类与配置 NamesrvController NamesrvConfig NettyServerConfig RouteInfoManager 3.启动与关闭流程 3.1.步骤一 3.2.步骤二 3.3.步骤三 NameServer 1.架构设计 消息中间件的设计思路一般都是基于主题订阅与发布的机制,RocketMQ也不例外.RocketMQ中,消息生产者(Producer)发送某主题的消息到消息服务器,消息服务器对消息进行持久化存储,而消息消费

随机推荐