点击上方“方志朋”,选择“设为星标”

回复”666“获取新整理的面试资料

来源:http://rrd.me/ej56f

  • 1、背景

  • 2、如何进行分层

    • 2.1、阿里规范

    • 2.2、优化分层

  • 3、分层领域模型的转换

  • 4、总结


1、背景

说起应用分层,大部分人都会认为这个不是很简单嘛 就controller,service, mapper三层。看起来简单,很多人其实并没有把他们职责划分开,在很多代码中,controller做的逻辑比service还多,service往往当成透传了,这其实是很多人开发代码都没有注意到的地方,反正功能也能用,至于放哪无所谓呗。这样往往造成后面代码无法复用,层级关系混乱,对后续代码的维护非常麻烦。

的确在这些人眼中分层只是一个形式,前辈们的代码这么写的,其他项目代码这么写的,那么我也这么跟着写。但是在真正的团队开发中每个人的习惯都不同,写出来的代码必然带着自己的标签,有的人习惯controller写大量的业务逻辑,有的人习惯在service中之间调用远程服务,这样就导致了每个人的开发代码风格完全不同,后续其他人修改的时候,一看,我靠这个人写的代码和我平常的习惯完全不同,修改的时候到底是按着自己以前的习惯改,还是跟着前辈们走,这又是个艰难的选择,选择一旦有偏差,你的后辈又维护你的代码的时候,恐怕就要骂人了。

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

  • 方便后续代码进行维护扩展;

  • 分层的效果需要让整个团队都接受;

  • 各个层职责边界清晰。

2、如何进行分层

2.1、阿里规范

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

开放接口层:可直接封装 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层类似

最上层controller和TService是我们阿里分层规范里面的第一层:轻业务逻辑,参数校验,异常兜底。通常这种接口可以轻易更换接口类型,所以业务逻辑必须要轻,甚至不做具体逻辑。

Service:业务层,复用性较低,这里推荐每一个controller方法都得对应一个service,不要把业务编排放在controller中去做,为什么呢?如果我们把业务编排放在controller层去做的话,如果以后我们要接入thrift,我们这里又需要把业务编排在做一次,这样会导致我们每接入一个入口层这个代码都得重新复制一份如下图所示:

这样大量的重复工作必定会导致我们开发效率下降,所以我们需要把业务编排逻辑都得放进service中去做:

Mannager:可复用逻辑层。这里的Mannager可以是单个服务的,比如我们的cache,mq等等,当然也可以是复合的,当你需要调用多个Mannager的时候,这个可以合为一个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类来传输。

每一个层基本都自己对应的领域模型,这样就导致了有些人过于追求每一层都是用自己的领域模型,这样就导致了一个对象可能会出现3次甚至4次转换在一次请求中,当返回的时候同样也会出现3-4次转换,这样有可能一次完整的请求-返回会出现很多次对象转换。如果在开发中真的按照这么来,恐怕就别写其他的了,一天就光写这个重复无用的逻辑算了吧。

所以我们得采取一个折中的方案:

1、允许Service/Manager可以操作数据领域模型,对于这个层级来说,本来自己做的工作也是做的是业务逻辑处理和数据组装。

2、Controller/TService层的领域模型不允许传入DAO层,这样就不符合职责划分了。

3、同理,不允许DAO层的数据传入到Controller/TService。

4、总结

总的来说业务分层对于代码规范是比较重要,决定着以后的代码是否可复用,是否职责清晰,边界清晰。

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

最后,如果你的团队有更好的分层,或者上面所描述的有什么错误的地方还请留言指正一下。

热门内容:   

  

  • 可能是国内第一篇全面解读Java现状及趋势的文章

  • 终于明白 Java 为什么要加 final 关键字了!

  • nginx 反向代理和负载均衡策略实战案例

  • Spring Boot + Mybatis 多模块(module)项目的完整搭建教程

  • 不用找了,大厂在用的分库分表方案,都在这了!

  • Spring Boot + Vue + Shiro 实现前后端分离、权限控制

  • 学 Redis ,至少要看看这篇!7000 字小结

  • 系统运行缓慢,CPU 100%,以及Full GC次数过多问题的排查思路

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡

优秀的 Java 项目代码都是如何分层的?相关推荐

  1. 优秀的 Java 项目,代码都是如何分层的?

    点击上方 "程序员小乐"关注, 星标或置顶一起成长 每天凌晨00点00分, 第一时间与你相约 每日英文 Things in this world are temporary. If ...

  2. 码云上面优秀的java项目_秒建一个后台管理系统?用这5个开源免费的Java项目就够了...

    以下推荐项目都是码云上的优质项目,并且都是项目快速开发脚手架,代码质量什么的无法保证能有多好,毕竟很多也是个人开发,或多或少也有个人色彩影响. 不过既然开源出来,这么多人参与,一般情况下项目整体质量可 ...

  3. 优秀的代码都是如何分层的?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来源:http://t.cn/RdrmI7i 1.背景 说起应用分 ...

  4. 优秀的 Java 项目是如何分层的?

    1.背景 说起应用分层,大部分人都会认为这个不是很简单嘛 就controller,service, mapper三层. 看起来简单,很多人其实并没有把他们职责划分开,在很多代码中,controller ...

  5. 优秀的代码都是如何分层的

    1.背景 说起应用分层,大部分人都会认为这个不是很简单嘛 就controller,service, mapper三层.看起来简单,很多人其实并没有把他们职责划分开,在很多代码中,controller做 ...

  6. 你知道吗?优秀的代码都是这样分层的!

    点击上方 "程序员小乐"关注公众号, 星标或置顶一起成长 每天早上8点20分, 第一时间与你相约 每日英文 Hold on to what makes you happy. Don ...

  7. java class 文件分析_大概优秀的java程序员都要会分析class文件吧

    相信大家在学java的时候都会听到这样的一些结论: enum 是一个类 泛型的实现使用了类型擦除技术 非静态内部类持有外部类的引用 需要将自由变量声明成final才能给匿名内部类访问 ... 初学的时 ...

  8. Java项目代码依赖包安全漏洞检测插件Dependency Check

    最近在搞Java的后端项目,需要更新jar依赖包,找到了一个jar包漏洞检测的插件Dependency Check. Dependency-Check是OWASP(Open WebApplicatio ...

  9. 优秀的Java程序员都在看哪些书?

    目录 一.立志存高远,笃行践初心 二.经典书籍 1.Java核心技术 2.Java编程思想 3.Java语言程序设计 4.Effective Java中文版(原书第3版) 5.Java并发编程实战 6 ...

最新文章

  1. linux7提示软件安装源位置不对,详解 RHEL7.1 yum源配置与软件安装
  2. 微博 用户画像_分析用户画像?从微博数据采集开始!
  3. 无法读取配置节aspnetcore_传奇列表为什么会读取失败?
  4. 【c语言 gcc9.1.0环境下编译报错】error: ‘true’ undeclared (first use in this function)
  5. IDEA 中的.iml文件和.idea文件夹 ( 隐藏方式 )
  6. codeforces B. Strongly Connected City(dfs水过)
  7. 掌握了AI这些点,面试官的天选之子就是你
  8. Git 版本控制原理
  9. CodeForces-1040B Shashlik Cooking(贪心)
  10. Matlab-CSMA_CA,pure ALOHA,时隙ALOHA协议性能对比分析仿真
  11. Android TextView设置下划线
  12. GooglePlay商店如何优化
  13. PHP 调用金山词霸API获取音标和音频
  14. 主从复制报错Fatal error:The slave I/O thread stops because master and slave have equal MySQL server UUIDs;
  15. 用深度学习做命名实体识别(四)——模型训练
  16. 神武4手游等待服务器响应,《神武4》手游快速告别自闭 还能这样玩?
  17. json文件怎么写注释
  18. 英语语法:定语从句讲解
  19. 亚马逊美国站12岁以下儿童产品 CPSIA测试标准
  20. ESP32中继模式STA+AP共存

热门文章

  1. 异常处理机制(Begin try Begin Catch)
  2. [bzoj2333] [SCOI2011]棘手的操作 (可并堆)
  3. 《lua程序设计(第二版)》学习笔记(五)-- 函数基础
  4. 不错的威盾PHP加密专家解密算法
  5. 【青少年编程】黄羽恒:加减乘除法小测试
  6. 【ACM】【STL】stack应用
  7. 【数据结构】顺序串的插入算法,删除算法,连接运算,顺序串求子串算法
  8. 属于python文件的操作有_Python的文件操作
  9. 腾讯联合国家天文台启动探星计划,优图AI可提升120倍数据处理效率
  10. 认知推理下的常识知识库资源、常识测试评估与中文实践项目索引