本文上回书接《这是DDD建模最难的部分(其实很简单)》,欢迎关注我的同名公众号。
https://mp.weixin.qq.com/s/HZKMLF0_I10iczzp2mAR-w
 

故事背景

2013年中,我们的Java后端团队为了落地DDD,全面引入了dotnet技术栈,具体过程和成果,可以看我的B站频道《Java8 到 .NET8,团队升级报告 - 第二弹》https://www.bilibili.com/video/BV14YgYedE1f
 
在近半年的时间,我将自己落地DDD的实践经验进行提炼和总结,以公众号文章和B站视频的方式分享出来,与更多的网友建立链接和交流,得到了很多肯定反馈,也因为大家提供的视角,使得我自己对DDD的认知有了更深层次的迭代。
 
目前我们借助dotnet强大的生态以及csharp优良的语言设计,已经可以非常丝滑地用代码表达模型和业务,整个软件交付的体验和效率,获得了前所未有的进步。我们netcorepal-cloud-framework框架在这个过程中也得到了进化和可用性验证,我们坚信找到了一套更加务实的软件设计认知和方法论。
 

Javaer太难了

由于我们团队实际上还是Java和csharp双技术栈,于是我们萌生了一个想法,是否可以让我们的Java项目交付过程也如此地丝滑?带着这个想法,我们开始在Java生态中寻找可以帮助我们构建出类似csharp框架效果的组件:
 
  • Web框架: aspnetcore vs springboot
  • ORM:EntityFrameworkCore vs JPA
  • 中介者模式:MediatR vs ?
  • 事件的最终一致性实现:CAP vs ?
 
其中“中介者模式”和“事件的最终一致性”实现我们没有找到合适的替代品,经过分析,“中介者模式”并不是必须的,虽然最终实现起来,没有csharp那么优雅,但并不影响对建模设计的实现,但“事件的最终一致性”这个组件,我们认为是必不可少的,我们建模最底层的模型就是“命令-事件”模型,没有事件处理的健壮性,意味着最终系统的健壮性无法保障,最终无法满足业务对可用性的要求。
 

事件的最终一致性

 
在我们的建模模型中,是在命令处理逻辑中,由领域模型发出事件,而事件如果要在微服务间传递,我们期望达到的效果如下:
 
  1. 如果命令处理逻辑成功,即对应的数据库事务提交成功,则确保事件一定能够发出;
  2. 如果命令处理逻辑失败,即对应的数据库事务回滚,则确保事件一定不发出;
 
在需求层面,我们并不要求系统确保事件“确定只发一次”,我们知道,这个要求的技术实现难度远远大于前面的两个要求,而且业务可以做幂等处理解决重发的问题。
 
下图展示了我们csharp版本中关于“命令-事件”的建模实现,以及事务的具体实现:

 
在我们csharp的版本,我们使用了比较流行的CAP组件,https://github.com/dotnetcore/CAP,这个组件本质上是实现了outbox模式,通常也叫“发件箱模式”,借助这个组件,我们很轻易就实现了对于事件的最终一致性。
 
下图来自CAP组件的介绍页面,展示了发件箱模式的具体工作原理:
 
 
 
 
 
 
 
 
 
 
 
 
 
从原理上看,发件箱模式并不是一个复杂的能力,我们认为一向以生态好为优点的Java生态,也一定有类似且流行的组件,很不幸的是,我们在互联网以及能够触达的Java圈子里调研一番之后,得出了如下结论:
  1. Java生态有关于分布式事务的实现,例如:JEE,JBoss等,但目前基本没有团队在用了;
  2. Java生态没有现成的类似CAP这样的组件可以开箱即用;
 
上述结论仅表示我们目前的认知和信息渠道,如果有大佬能够给指个路,不甚感激!
 

cap4j

 
基于前面的结论,为了实现Java项目的DDD代码体验实践,我们开源了一个cap4j项目,期望能将CAP项目的能力移植到Java生态,项目地址:https://github.com/netcorepal/cap4j
该项目目前实现了JPA+RocketMQ的组合,我们规划在未来支持更多的ORM和MQ中间件,同时也会支持与CAP组件的协议兼容,以实现Java、dotnet异构架构的进一步融合。也欢迎大家为项目贡献代码和想法。
 

最后

 
关于技术生态这件事,可以说Java的生态好,但其它语言的生态我认为也都不差,在各自的领域都有非常多的优点。我在各个评论区,总是能看到各种不切实际的偏激言论,感受到种种的恶意。期望各个语言的技术栈从业者,能够更友好地交流,大家都是软件工程师,满足业务需求,实现商业价值,才是大家的更应该关注的。

为了给Javaer落地DDD,我们不得不写开源组件的更多相关文章

  1. freemarker写select组件(一)

    freemarker写select组件 1.宏定义 <#macro select id datas> <select id="${id}" name=" ...

  2. freemarker写select组件(五)

    freemarker写select组件 1.宏定义 <#macro select id datas value="" key="" text=" ...

  3. freemarker写select组件(四)

    freemarker写select组件 1.宏定义 <#macro select id datas value="" key="" text=" ...

  4. freemarker写select组件(三)

    freemarker写select组件 1.宏定义 <#macro select id datas value="" key="" text=" ...

  5. freemarker写select组件(二)

    freemarker写select组件 1.宏定义 <#macro select id datas value=""> <select id="${id ...

  6. django-admin 仿写stark组件action,filter筛选过滤,search查询

    写在StandLi里面的方法都是通过ModelSubject这个类里面的stand_li方法,在它里面用StandLi这个类实例化出来一个对象,这个实例化出来的对象把数据传给前端HTML模板进行渲染, ...

  7. vue-class-component 以class的模式写vue组件

    vue英文官网推荐了一个叫vue-class-component的包,可以以class的模式写vue组件.vue-class-component(以下简称Component)带来了很多便利: 1.me ...

  8. 使用docsify 写开源文档

    使用docsify 写开源文档 官网:https://docsify.js.org/#/ docsify 是一个动态生成文档网站的工具.不同于 GitBook.Hexo 的地方是它不会生成将 .md ...

  9. 手写开源ORM框架介绍

    手写开源ORM框架介绍 简介 前段时间利用空闲时间,参照mybatis的基本思路手写了一个ORM框架.一直没有时间去补充相应的文档,现在正好抽时间去整理下.通过思路历程和代码注释,一方面重温下知识,另 ...

  10. 手把手教你提交Jar包到Maven公共仓库 | 萌新写开源02

    在上一篇文章中,我介绍了自己的SpringBoot Starter项目,可以让我们使用注解的方式轻松地获取操作日志,并推送到指定数据源. 之前,我的项目开源在Github上,大家想要用我的项目,还得把 ...

随机推荐

  1. C# 循环枚举

    foreach (int eemun in Enum.GetValues(typeof(类名))) { string sName = Enum.GetName(typeof(类名), eemun);/ ...

  2. C#如何创建一个可快速重复使用的项目模板

    写在前面 其实很多公司或者资深的开发都有自己快速创建项目的脚手架的,有的是魔改代码生成器实现,有的直接基于T4,RazorEngine等模板引擎打造:但无论如何,其最终目的其实就是搭建一个自定义项目模 ...

  3. Win10任务栏图标居中

    win+q键搜索并打开字符映射表 点击第五行的空白字符,然后先后点击下方的选择以及复制 在桌面新建一个文件夹,然后重命名,将刚才复制的空白字符粘贴进去,如图,这样我们就拥有了一个空白名称的文件夹 在任 ...

  4. 安装tesserocr

    1.下载安装包 这个包不能使用pip安装 可以在这里找到适合自己的版本安装: https://github.com/simonflueckiger/tesserocr-windows_build/re ...

  5. yolov1-yolov5 网络结构&正负样本筛选&损失计算

    学习yolo系列,最重要的,最核心的就是网络模型.正负样本匹配.损失函数等三个方面.本篇汇总了yolov1-yolov5等5个版本的相关知识点,主要看点是在yolo框架搭建.初学者可以通过相关篇章搭建 ...

  6. 【排行榜】Carla leaderboard 排行榜 运行与参与手把手教学

    此分支主要供参与leaderboard排名使用,介绍如何构建队伍,提交自己代码,此部分较为简单,主要是基本教学与演示:后续可以参考更多的开源代码进行学习等. 基本参与此榜单的大多都是学校和实验室,还是 ...

  7. 写sql语句思路--28道关于教师、学生、成绩表的练习题---个人思路

    针对学生教师的28道练习题的思路 链接:https://pan.baidu.com/s/1TgqFAe7i0PAkZOm47-Jd0A 提取码:vvi6 部分截图如下: -- sql 28道练习题答案 ...

  8. pysnmp 获取设备 mib

    snmpwalk 指令获取设备 mib snmpwalk -v 1 -c public ip .1 > ip.mibs pysnmp 获取设备 mib 安装环境 pip3 install pys ...

  9. Mac Eclipse 常用快捷键汇总

    寻找类:shift+command+t 删除当前行:command+d 上移当前行代码:option+↑ 下移当前行代码:option+↓ 复制当前行至下一行:option+command+↓ 复制当 ...

  10. 把nodejs程序打包成可执行文件

    在写好之后的nodejs程序,想发给同事的电脑上运行程序,就不得不下载node环境,还要安装第三方依赖包,非常的麻烦. 因此,可以借助一些插件来完成nodejs程序的打包,变成可以执行的文件. 将No ...