FAQ:
在谈naga之前,先谈一下阿里开源的 cola ( https://github.com/alibaba/COLA ), 官方没有对cola给出一个详细严谨的定义,这里也不纠结。 cola 分为两部分,一部分是架构,一部分是组件。 简单地理解, 官方给按照下面图示做了一个架构上的分层划分, 并提供了一些规范化的组件,比如dto,exception,statemachine,extension-starter 等。
具体的实现上是通过 maven来生成 指定的archetype的代码布局,并在pom文件里导入了这些规范化组件。
然而对于一个具体的应用来说,只有一个代码布局规范和一些极小集合的基础抽象组件库是不够的。 要脑海中的概念设计图,映射到代码中来, 这种映射通常都是由程序员完成的, 当然,对于一个具有懒惰美德的程序员来说,能尽量多让机器多干活自己少干活是一种内在的追求, 于是naga 就应运而生。
naga与cola的关系是互补的关系,更确切的说是在cola生成的代码框架基础上,增加了以下的功能:
- 提供一个dsl来描述领域类及其之间的关系。 这个dsl是兼容java语法并提供简化的语言,并将该ddd模型翻译成 符合cola架构风格标准的代码。
- 提供一个完整的标准的微服务运行时支撑环境。这个运行支撑环境将会集成许多常用的框架和组件库。
- 提供一个统一的完整的可视化ddd概念模型。
- 提供ide插件,做逻辑层面的校验和语法自动完成。 简单的说,你可以理解为:naga是一个基于 cola 的代码生成框架,它用于帮助使用DDD的开发者减少重复的同质性体力劳动,节省开发时间,以及获得更大的业务视角。
我在印度旅行的时候,对这个叫naga的人身蛇尾的类似伏羲女娲的生物感到莫名的眼熟。后来查了一下,naga一词来自于佛教,是天龙八部中的龙部,在华严经中有多次提到,当有人真正修行佛法时,会有naga护法。感觉挺形象的,这个项目就取名naga吧,希望能给DDD的信徒护法。
别激动, 上面那个是蓝图,是画饼。 这个项目是我在2023年开发别的项目的过程中剥离出来的,仅仅完成了 dsl 语言的设计和简单的生成,以及集成了一些常用的框架和开发组件(尚未好好规划)。 但后续会按照饼的方向拱进。 之所以现在发布出来,有两个原因:
- 最核心的部分dsl的语法设计趋于稳定,第一个版本的代码实现也勉强可用。我也需要一些建议和反馈。
- 相关的工作量还是蛮大的,看看有没有志愿者愿意参与。
当然,即使没人感兴趣,或者没有人参与,我也会继续坚持将这个画饼实现,将这它打造成我的架构平台开发的RAD工具,因为我坚信微服务的下一步将会朝DDD的方向发展,事实上,微服务是一种早期的,无意识的,没有从业务角度进行领域划分的DDD。
主要动因是在使用cola的过程中,被重复的琐碎的体力活烦扰,这种烦扰不仅仅是体力上的,还是心理上的。
ddd方法论的主要理念是采用分治法,把大的问题领域切割成小的问题领域,逐个击破,并促使小领域的所有参与者在这个领域内对所有的概念定义达成清晰无误的共识,以减少因沟通带来的信息差(信息差带来的影响是制约团队输出效率的重要因素,因此团队需要不停的邮件,会议,im或者面对面沟通来对齐)。
cola (https://github.com/alibaba/COLA) 是一个基于DDD理念的架构风格。cola提供了一个基于实践沉淀的分层脚手架,给出一系列的规范,(如组件,结构,包,结构,命名等)。以便开发者方便地实现DDD方法论。于目前来看是非常合理和分层清晰的。然而在具体的使用过程中, 开发者仍然需要花不少的精力去处理一些常规的琐碎的活,比如 不同层之间值对象的转换,不同上下文之间的概念的映射等。处理这些琐碎的工作是简单的,但由于不断的重复,即使有ide的自动工具,也苦不堪言,尤其是当设计处于不稳定阶段,需要经常变更的时候,开发者的精力不应该浪费在这上面。
因此,产生了写一个基于cola的代码生成器来减少重复的开发,变更维护,和测试工作量的想法,并付之实现。 像orm框架那样,你描述清楚对象以及对象之间的关系,就会生成相关的数据库和查询实现类和方法,naga 在你描述清楚你的领域类及其之间的关系之后,也将自动生成相关的框架代码。
当前版本还是未整合,比较零散。
是在使用cola的来开发别的项目的时候用到的一些常用框架和组件。在确保兼容的情况下,各个组件尽可能采用最新版本, 后续他们会以starter的方式集成项目中来 。 在正式版推出来之前,你可以忽略掉这个分支。
组件 | 版本 | 最新版本 | 说明 |
---|---|---|---|
jdk | 17 | 21 | - |
springboot | 3.1.6 | 3.2.0 | - |
lombok | 1.18.30 | 1.18.30 | - |
mybatis-plus | 3.5.4.1 | 3.5.4.1 | 简单orm框架 |
jakarta.el-api | 5.0.1 | 5.0.1 | - |
fastjson | 2.0.42 | 2.0.42 | |
junit-jupiter | 5.10.1 | 5.10.1 | 测试框架 |
junit-platform-suite-engine | 1.10.1 | 1.10.1 | 测试套件 |
testcontainers | 1.19.3 | 1.19.3 | 跑测试用例很爽 |
flyway | 10.0.1 | 10.0.1 | 数据库维护用 |
commons-lang3 | 3.14.0 | 3.14.0 | - |
druid | 1.2.20 | 1.2.20 | jdbc连接池 |
jakarta.xml.bind-api | 4.0.1 | 4.0.1 | - |
swagger-starter | 2.2.0 | 2.2.0 | api doc |
swagger-ui | 1.7.0 | 1.7.0 | |
shardingsphere | 5.4.2-SNAPSHOT | 5.4.1 | 修改了官方的版本 |
- 定制的DSL(已经实现)
提供简洁的语法描述,该语法在兼容java语法的基础上,增加了对领域描述的语法元素。 在大多数时候,可以很简洁地描述,极端情况下,可以使用java 语法描述。 - 基于cola框架的标准过程代码生成
- adapter
-
- app
-
- client
-
- domain
-
- infrastructure
-
- 各种vo,dto
-
- 界限上下文映射 (todo)
-
- 测试用例生成 (todo)
- 允许定制自定义的标准过程代码模板 当默认的标准模板不满足要求时,可以创建自定义模板
- 领域全景图 (todo)
-
- 领域之间的交互关系
-
- 领域与子领域的从属关系
-
- 子领域之间的交互关系
-
- 界限上下文内的结构
-
- 界限上下文之间的交互关系(含映射)
- ide插件(todo)
目前考虑实现 intellj idea 的插件,来帮助编辑语法文件。
- 切换到分支 naga-dsl: git checkout naga-dsl
- 执行 mvn clean package
- 运行 App 即可生成,注释掉 删除生成文件的那行文件就能看到生成文件(后续会修改成命令行选项的方式)
在面向对象崛起的远古时代,开发者也面临着应用层的面向对象层级结构转化向数据层的面向关系模式的二维表结构的不匹配的情况, 因此诞生了 hibernate ,mybatis 这类的orm框架。orm框架的本质是将面向对象中的对象,对象关系, 及受限的操作集合(crud) 自动映射到 关系数据库中的表,表关系及受限的操作集合(crud)中。
naga也与此类似,是将依据ddd方法论得到的领域模型概念体系映射到cola的代码框架。这个过程是自动化的,它将帮助你减少很多重复的创建,转换的工作,加快你的开发效率。
在一个有10个领域概念的小领域内,在概念明晰的情况下,即使借助ide的很多辅助代码生成的功能, 也仍然需要至少30分钟,(这是乐观情况,实际上受各种因素影响,开发者不可能做到无视各种异常地无脑流输出),用naga,只需要一键生成。
在使用cola的过程中, 当开发者定一个领域类的时候, 连带着需要搞一大堆额外的处理,需要从 adapter 到 infrastructure 每一层都要检查一遍,定义各种类,解决各种转换,调试是否有bug等, 一套打下来,我已经忘记了我最初要做什么了。这个是分散我的注意力的,打断了思维的连贯性。 采用naga,可以让你脱离这些细节,在生成相关代码框架后, 找到需要的位置填写业务逻辑, 让心情变得更愉快。
对于一个DDD的初用者,naga生成的模板代码是推荐的标准流程,可以很好地帮助开发者在设计层进行复用,哪怕初学者对DDD了解并不深。这有点像辅助驾驶系统一样,防止驾驶员犯大的错误。
DDD的方法论提倡分割成小领域,每一个领域都由不同的团队进行开发。但不同团队之间对DDD的理解和实践都可能不一致,这导致代码命名,功能布局,代码结构等都不一样。 naga提供了一个自概念层生成代码层的能力,只要在概念层达成一致,那么在代码层也会生成风格一致的实现。并且提供了标准之外的定制话能力,以便于团队间的按照期望的任意风格保持一致。
虽然DDD方法论出现的时间比微服务架构方法论出现的时间要早。但从进化逻辑上来看,DDD方法论是微服务架构方法论的下一个阶段的进化。微服务架构方法论有点类似本能进化的状态,凭借设计师的能力和理解对服务进行拆分和组合,DDD方法论在微服务基础上以业务为导向按其方法论分割小的业务领域,因此都会有一个。但微服务都有一个通病,就是业务逻辑零散。当业务变更范围很跨多个微服务或者多个领域时,去确认这个变更影响和实施这个变更影响是的成本是比较昂贵的, 需要去多个领域和微服务去检查,要么去找相关的文档,要么去找相关的人,当然有业务架构师存在的公司,这个职责就落在业务架构师身上,业务架构师也需要经过这个信息汇总加工处理的过程。 naga提供了一个可视化全景图,能够以直观的方式来把握整个业务概念体系。
DDD鼓励一个界限上下文内的实现为一个微服务,微服务之间至少会有进程的隔离级别的强制,这会带来很好的隔离性。但很多庞大的应用系统都是经过一个渐进式的演化过程而来,很多系统在开发之初,也并不复杂,硬性地将其拆分成独立服务去开发和部署,能满足隔离性的要求,但也会带来额外的工作量。如果将几个微服务混在一个项目中开发和部署,又常常会混淆了边界,比如为了便利而产生很多的跨界调用和访问,这些本来应该是rpc,为了方便,实现成了本地调用,等到需要拆分的时候,又要花很多时间来检查和处理,但通常都是屈服于业务安全,没有人愿意去冒这个风险主动去作这个事情,除非有其他的无法忍受的问题出现,比如性能,提交冲突等什么的。 naga的生成代码框架会确保跨界限上下文的访问要经过特殊的处理层, 可以在这个处理层里根据本地的注册服务情况来决定是本地调用还是远程调用。这使得它提供一个可以按照最细为界限上下文来切割的粒度来切割服务,进行独立部署。
这只是一个为了自己的便利开发的工具,但在开发的过程中,冒出了很多的想法, 要想将这些想法的实现为可靠的工具, 还是需要很大的工作量的,感兴趣的朋友可以一起加入来玩玩。 联系方式: [email protected]
- 语法元素的定义
- 实现文件生成
- 实现
- 实现标准模板和自定义模板
- 实现领域模型关系图生成
- 实现约束关系
- 实现生成选项控制
- 语法重新格式化功能,将零散的定义重新整合输出
- 插件+扩展, 比如定制 布局 和 样式