当前位置: 首页 > 图灵资讯 > 技术篇> Java项目是如何分层的

Java项目是如何分层的

来源:图灵教育
时间:2023-05-30 09:26:44

阅读文本大约需要3分钟。

  • 1、背景
  • 2、如何分层?
  • 2.1、阿里规范
  • 2.2、优化分层
  • 3、分层模型的转换
  • 4、总结
1、背景

说到应用分层,大多数人会认为这不是很简单 controller,service, 三层mapper。看似简单,其实很多人并没有把自己的职责分开。在很多代码中,controller做的逻辑比service多,service往往被视为传播。这其实是很多人开发代码时没有注意到的地方。反正功能也可以用。放在哪里没关系。这往往导致后代码无法重用,层次关系混乱,后续代码的维护非常麻烦。

的确,在这些人眼里,分层只是一种形式,前辈的代码是这样写的,其他项目的代码是这样写的,所以我也是这样写的。然而,在真正的团队开发中,每个人都有不同的习惯。编写的代码必须有自己的标签。有些人习惯于编写大量的业务逻辑,有些人习惯于在service之间呼叫远程服务,这导致每个人的开发代码风格完全不同。当其他人随后修改时,我看到这个人写的代码与我通常的习惯完全不同,这是一个困难的选择,无论你是按照你以前的习惯改变还是跟随你的前任。一旦选择有偏差,你的年轻一代就会维护你的代码,恐怕你会责骂。

因此,一个好的应用分层需要具备以下几点:

  • 维护和扩展后续代码方便;
  • 整个团队都需要接受分层效果;
  • 各级职责边界清晰。
2、如何分层2.1、阿里规范

阿里编码规范中约束的分层如下:

 

Java项目是如何分层的_mvc

开放式接口层:可直接封装 Service 方法暴露成 RPC 接口;通过 Web 封装成 http 接口;进行 网关安全控制、流量控制等。

终端显示层:模板渲染和执行各端显示层。目前主要是 velocity 渲染,JS 渲染, JSP 渲染、移动终端显示等。

Web 层:主要转发访问控制,验证各种基本参数,或简单处理不再用的业务。

Service 层:相对具体的业务逻辑服务层。

Manager 层:一般业务处理层,具有以下特点:1. 对于第三方平台封装层,预处理返回结果和异常转换信息;2. 缓存方案、中间件通用处理等Service层通用能力下沉;3. 与DAO层交互,重用多个DAO的组合。

DAO 层:数据访问层和底层 MySQL、Oracle、Hbase 数据交互。

阿里巴巴规定中的分层相对清晰、简单、清晰,但描述仍然过于简单。此外,许多学生仍然不知道service层和manager层之间的关系,这导致许多项目中没有manager层。以下是如何在具体业务中实现分层。

2.2、优化分层

从我们的业务发展中总结出一个理想的模型。在这里,我们应该首先解释一下,由于我们的RPC框架选择thrift,它可能比其他RPC框架多一层,如dubbo,其功能类似于controller层

 

Java项目是如何分层的_restful_02

上层controller和TService是我们阿里分层规范的第一层:轻业务逻辑、参数验证、异常底部。通常这个接口很容易更换接口类型,所以业务逻辑一定要轻,甚至不做具体的逻辑。

Service:业务层复用性低。建议每个controller方法都要对应一个service,不要把业务安排放在controller中。为什么?如果我们把业务安排放在controller层,如果我们将来想访问thrift,我们需要在这里再次安排业务,这将导致我们必须复制每个访问入口层的代码,如下图所示:

 

Java项目是如何分层的_spring_03

如此大量的重复工作必然会降低我们的发展效率,因此我们需要将业务安排逻辑放入service中:

 

Java项目是如何分层的_restful_04

Mannager:逻辑层可重复使用。这里的Mannager可以是单一的服务,如我们的cache、mq等,当然也可以是复合的,当你需要调用多个Manager时,这可以合并为Mannager,如逻辑连表查询等。如果是httpmannager或rpcmannager,则需要在这一层进行一些数据转换

DAO:数据库访问层。主要负责“操作数据库的表,映射到java对象”。dao应该只允许自己的Service访问,其他Service必须通过相应的Service访问我的数据。

3、分层模型的转换

在阿里巴巴编码规则中列出了以下几个领域的模型规则:

  • DO(Data Object):数据源对象通过DAO层向上传输,与数据库表结构一一对应。
  • DTO(Data Transfer Object):Service或Manager向外传输数据传输对象。
  • BO(Business Object):业务对象。包装业务逻辑的对象由Service层输出。
  • AO(Application Object):应用对象。在Web层和Service层之间抽象的复用对象模型,非常接近显示层,复用度不高。
  • VO(View Object):显示层对象通常是Web传输到模板渲染引擎层的对象。
  • Query:数据查询对象,各层接收上层查询请求。注意查询包装超过2个参数,禁止使用Map类传输。

Java项目是如何分层的_spring_05

每个层基本上都有自己相应的领域模型,这导致一些人过于追求每个层都使用自己的领域模型,从而导致对象可能出现三次甚至四次转换在请求中,当返回也会出现3-4次转换时,所以可能有一个完整的请求——返回将出现多个对象转换。如果在开发中真的遵循这一点,恐怕就不要写别的了,一天就写这个重复无用的逻辑吧。

因此,我们必须采取一个妥协计划:

1、允许Service/Manager操作数据领域的模型。在这个层面上,我自己的工作也是业务逻辑处理和数据组装。

2、Controller/TService层的领域模型不允许进入DAO层,因此不符合职责划分。

3、同样,DAO层的数据也不允许传输到Controller/TService。

4、总结

一般来说,业务分层对代码规范更为重要,这决定了未来的代码是否可以重用,责任是否明确,边界是否明确。

当然,这种分层其实是见仁见智的, 团队中的每个人都有不同的分层习惯,所以很难权衡一个标准标准。一般来说,只要职责逻辑清晰,后续维护容易,就是一个很好的分层。

最后,如果你的团队有更好的分层,或者上面描述的错误,请留言纠正。