Java项目分层结构分析

发布时间:2023-06-17

统计字数:1812 字

阅读时间:10 min read

Java项目分层结构分析

简介

该文章是以 项目分层结构 为主题,主要讲述了目前我所了解到的常见的单体项目,微服务项目所使用的项目结构。

注意!这里说的并不是项目架构,而是项目结构。从我们所知的也是最常见的 MVC 模式下,项目模块会被分成 Controller,Service 和 Mapper 层,当然也有人将 Mapper 层命名为 Dao 层,这个没关系,反正都是对数据库进行操作的层就是了。

上面则是经典 MVC 模式下的项目分层结构,Controller 层处理外部的 api 请求,Service 层则是处理具体的逻辑,而 Mapper 层则是操作数据库,这样就形成了一个单独的模块了。

这种项目分层简单而实用,不仅可以快速开发一个接口,更容易进行维护。我从之前的一些教训中学到,有的时候越是简单的东西越高效。可是简单就意味着可能在后续拓展中会变得复杂,以及在某些场景中的不适用。

过程

1. 经典 MVC 项目分层

在传统的 MVC 分层架构中,我们项目一般的结构是这样子的,分别分成 Controller,Service 和 Mapper / Dao 层,每一层只处理跟自己相关的逻辑。

image-20230221083415145

从文件树看是这样子的

src
├─main
│  ├─java
│  │  └─com
│  │      └─example
│  │          └─springbootdemo
│  │              ├─controller
│  │              ├─domain
│  │              ├─mapper
│  │              └─service

这样子的项目结构应对普通的 CRUD 操作是完全没问题的,但是当我们项目中混入了许多复杂逻辑的时候,Service 层就会显得尤其臃肿。

例如我有一个逻辑是需要从两个 Mapper 中获取数据,并进行数据处理,假如说该数据处理逻辑较为复杂,那我们还是放在一个方法中的话,那么整的一个方法的行数就会超级多,无法快速地阅读方法的整体逻辑。

image-20230221090541994

如果将这数据处理操作重构成一个独立的私有方法的话,那么这一个 Service 类也会变得很”大“,当我们需要查看其他的逻辑方法的时候,也会难以寻找。

2. 阿里巴巴开发手册中的分层

假如有阅读过阿里巴巴开发手册的童鞋,就会发现在 工程结构 这一章中,有提到这么一个分层结构。

image-20230221084712667

在 Service 层下再增加一层 Manager 层,那么其作用也在开发手册里面说出来了,我也不再叙述。

在实际项目中,我们更多的是使用 Manager 层来对数据库进行增,删,改操作,这是因为项目中使用到的大部分是 SpringBoot 框架,而我们进行这些操作的时候是需要开启事务的,但是如果你在进行这些操作前需要查询数据库,进行数据处理的话,那么该事务有可能会变成一个 长事务

除了这个作用之外,像手册里提到的 对Service层通用能力的下降 ,我们将原本 Service 层中的数据处理方法提取到 Manager 层中,那么除了 Service 层会保留主要的逻辑之外,这些逻辑方法也可以随便复用和组合这些通用方法。

image-20230221090750016

3. 独立分离业务和实体模块

以上项目结构其实已经足以应对单体项目了,但是在微服务架构下就有点麻烦了,因为微服务架构下我们会将项目进行分模块,以我的智慧社区为例,则会分成用户服务,文章服务,搜索服务,通知服务和认证服务等,且每个服务都拥有独立的数据库,相互的数据是隔离的。

但是每个相关联的服务都会不可避免的进行耦合,假如文章服务需要获取作者的信息就需要请求用户服务进行查询,获取请求结果。但是请求结果是一个用户的 VO 类,在文章服务模块中没有这个类呀,总不能每一个需要这个类的服务模块也在自个儿的模块上新增这个类吧。

那么这时候,我们就会发现其实每个服务相互耦合的地方很大一部分是实体类的耦合,那我们就可以尝试着将实体类分成一个独立的模块分出去,供其他模块引用。

image-20230221091712763

这样子分出一个独立 model 模块,其他服务模块如果使用到该服务的话,就可以直接引用该模块。

但假如要求微服务隔离性要比较高的话,那么也只能在目标微服务上构建实体类来进行接收了。

4. 新增加的module层

但是我们往往不会将服务分得太细,我们只会将主要的服务分离成微服务,这些主要的服务中有可能也会包含着很多服务,例如说文章服务中我并没有将评论服务和点赞服务分离出去。

首先微服务架构所要解决的一个问题是单体服务耦合度很大,当其中一个服务出现问题时,其他服务可能也会因此受到波及。然后就是分离成单独服务模块的话,它也会因此获得独立的资源来处理服务逻辑,获得更好的性能。

但是当一个服务的使用量暂时并没有特别突出的时候,我们一般不会将其分离出来。具体微服务的划分后面可能会单独出一个文档来说明。

但是如果到后期某一天,评论系统扛不住了,需要急切地独立出来做成一个微服务,那么我们有必要新增一个module层来管理各个子系统。

image-20230221093701915

我们将每一个子系统独立成一个软件包来管理,那么到后面某个子系统需要成为一个微服务的时候,我们就可以快速地构建起这个微服务。

总结

以前项目结构只是目前我所了解到的常用的项目结构,我们可以发现,从简单地分成 Controller,Service 和 Mapper 层到后面成为微服务架构后分成每一个子系统,复杂性不断地在提高,互相通信变得困难,但这是为了应对越来越复杂的场景而改变的。

其实有时候会觉得编程思想之间会比较矛盾,我们为了解除耦合,不断地进行分离,尽量不依赖于其他逻辑,可是为了进行代码复用,减少无效增加,我们不断地对通用方法进行分离复用,但是这个通用方法就会变得如同无人敢碰的堡垒一样,因为我们不知道优化了什么,修改了什么将会发生什么,牵一处而动全身。