SpringBoot2.X 工程代码分层最佳实践

716 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

简介

每个人对Spring工程的分层理解各不相同,在同一个公司里面最好使用相同的代码层次结构。减少沟通和Review的成本。

分层规范可以参考我之前的文章,我还是比较推荐用领域驱动模型设计的分层思想去做分层。

Java工程基建规范之代码分层

分层和命名规范

上层依赖下层,下层不能反向依赖上层

DDD分层规范.png

各个分层的职能

1、接口层

主要是对外交互的接口,比如Spring Cloud微服务Feign接口,提供外部依赖的包,主要定义一些接口,枚举,不能有一些资源的依赖, 避免各个服务之间存在强依赖。

image.png

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-openfeign-core</artifactId>
        <version>2.2.3.RELEASE</version>
    </dependency>
</dependencies>

保持接口层最纯粹和简单的依赖,会减少后面微服务调用各种版本依赖的问题,这个是踩过很多坑之后的经验。

2. 应用层

业务聚合层,大部分的业务逻辑在这一层封装, 比如一些规则校验。这边分为QueryService和AppService,对于很多简单的查询, QueryService 直接调用Infrastructure层即可,不需要经过领域服务层。 对于复杂的业务,需要调用领域层,通过聚合和领域服务实现业务功能。

3. 领域层

DDD 核心层,聚合根,实体,上下文,领域服务边界的划分。比如作为自动化营销服务可以分为流程引擎,规则引擎,状态机引擎,触达等等。

4. Infrastructure 基础设施层

主要是针对各种存储, 第三方防腐层适配器转换, 防腐层设计等等。

包结构和命名规范

REQ 接口请求参数后缀, 大写 RESP 接口请求返回参数后缀, 大写 DTO 数据传输对象,大写

image.png

事件定义

1、外部事件,比如RocketMQ 监听, Kafka 监听等等。
2、内部事件流程,采用Spring内部的Event

最佳实践

上面的案例是基于最近一个项目中的一些实践总结的分层设计相关的,每个公司的项目背景不同,有些项目很简单的CRUD , 是不是MVC分层就可以了,或者阿里开发者手册中的分层已经满足大部分业务开发场景的需要了。架构规范设计本身其实就是项目复杂度之间的博弈,六边形架构,洋葱架构不一定就是好的。

image.png

参考文章:

DDD领域驱动设计_靖节先生的博客-CSDN博客_ddd领域驱动设计