COLA实践代码
- 同步BiliBili视频
代码
- https://gitee.com/XuXiaoCong/cola-springboot-demo
- https://github.com/xuxiaocong/cola-springboot-demo
- 该项目为COLA+SpringBoot搭建的单体项目
适用人群
- 已有SpringBoot基础,使用SSM开发过项目
- 尝试DDD,并且落地项目
版本
- Java: 17
- COLA: 5.0.0/4.3.2
- SpringBoot: 3.2.6
# 下载代码
git clone https://gitee.com/XuXiaoCong/cola-springboot-demo.git
# 进入目录
cd cola-springboot-demo
# 下载依赖
mvn clean package
# 启动,使用Java17
java -jar start/target/start.jar
- 启动后,打开Swagger:http://localhost:8080/swagger-ui/index.html
COLA模块结构
- 模块结构图
与其他流行的框架层次做对比
模块 | 层级 | 作用 | 对比三层架构 (Controller、Service、Dao) |
---|---|---|---|
adapter | 适配层 | 一般放MVC的控制器,或其他路由和适配 | Controller |
client | 接口层 | 服务接口 | 相当于IService接口 |
app | 应用层 | client层的接口实现,业务代码 | 相当于ServiceImpl |
domain | 领域层 | 实体对象,充血模型,用面相对象设计 | 无 |
infrastructure | 基础设施层 | 全局设置、数据库操作、远程调用、转换器等 | 持久化层(DAO),Mapper、数据对象 |
start | 应用入口 | Application.java,application.yml |
功能
- 每个模块下包含几项主要功能
目录结构划分
- 先按照领域划分,如Order、Item、Stock
- 再功能划分,如model、ability、gateway
有一部分不需要用领域划分(个人理解)
- Adapter层,因为这个层一般放控制器,控制器本身就聚合了多个接口,没必要再划分领域
- Infrastructure层的config,因为配置一般都是全局配置,不使用用领域划分
模块介绍
start
- 启动入口
- 主要做项目设置,启用SpringBoot的功能
start/pom.xml
- 增加打包插件,打包之后重命名为"start.jar"(默认为"start-版本号.jar")
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
adapter
- 适配层,一般放MVC的控制器
- 控制器本身就聚合了多个接口,没必要再划分领域
包名 | 功能 | 备注 | 命名 |
---|---|---|---|
web | 处理页面请求的Controller | Mvc的控制器 | xxController |
wireless/mobile | 无线端/手机端的适配 | 很少不使用 | |
wap | wap端的适配 | 很少不使用 |
client
- 对外接口层,存放服务接口及入参出参
- 单体应用中,该层略显鸡肋,实际作用是在微服务架构中
- 本层先划分领域,再划分功能
包名 | 功能 | 备注 | 命名 |
---|---|---|---|
api | 服务接口 | interface | xxServiceI |
dto | api的入参、出参 | 可引用"cola-component-dto"组件 | 入参(读):xxQry,即Query 入参(写):xxCmd,即Command 出参:xxCO,即Customer Object |
app
- App层主要放业务代码,或称为胶水代码
- 本层先划分领域,再划分功能
包名 | 功能 | 备注 | 命名 |
---|---|---|---|
executor | 执行器,业务代码 | 根据读写数据分为Query和Command。Query可直接调用infrastructure的Mapper,Command一般不直接调用Mapper,而是使用Gateway操作 | 读数据类名:xxQryExe 写数据类名:xxCmdExe,作者习惯写成xxExe 同步方法:execute(xx) 异步方法:asyncExecute(xx) |
consumer | 消费者 | 消息队列消费者 | xxConsumer |
scheduler | 定时任务 | - | xxScheduler |
domain
- 领域层,核心业务
- 注意模型使用充血模型,使用面向对象写领域模型
- 本层先划分领域,再划分功能
包名 | 功能 | 备注 | 命名 |
---|---|---|---|
model | 领域对象,里面放充血模型 | 单一对象的操作放在领域对象中 如:用户改名、改密码 | - |
ability | 领域能力,包括DomainService | 多个对象间的操作 如:两个账户间的转账 | xxDomainService |
gateway | 网关接口,解耦利器 | 解耦底层数据 | xxGateway |
infrastructure
- 基础建设层
- 本层大部分需要先划分领域,再划分功能
- config一般是全局配置,不需要划分领域
包名 | 功能 | 备注 | 命名 |
---|---|---|---|
config | 全局设置 | 全局异常、环境变量参数、@Configuration注解的配置等 | - |
mapper | 数据库CRUD封装 | 如mybatis实现的数据库操作 | xxMapper |
mapper.dataobject | 数据对象 | 数据库对象,使用贫血模型(POJO) | 关系型:xxDO,即DataObject Mongo:xxDoc,即Document |
gatewayimpl | 网关实现 | 调用mapper实现数据交互 RPC/Http对接其他系统Api,实现数据交互 | xxGatewayImpl |
convertor | 转换器 | 数据对象(DO)、领域对象(Entity)、用户对象(CO)、数据转换对象(DTO)等各种"O"之间的转换 使用"Convertor"结尾 | xxConvertor |
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。