优秀的代码原来是这样分层的

作者 | 咖啡拿铁

来源 | t.cn/RdrmI7i

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、总结

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

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

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

【END】

近期热文

 
  • 面试珍藏:最常见的200多道Java面试题

  • 被一个熟悉的面试题问懵了:String...

  • 面试官:如何实现幂等性校验?

  • 年终盘点 | 2019年Java面试题汇总篇(附答案)

关注下方二维码,订阅更多精彩内容

朕已阅 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/546394.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试官 | 什么是 Lambda?该如何使用?

作者 | Mingqi来源 | zhihu.com/question/20125256/answer/3241213081.什么是Lambda?我们知道,对于一个Java变量,我们可以赋给其一个“值”。如果你想把“一块代码”赋给一个Java变量,应该怎么做呢?比如,我想把右边那…

面试官 | 线程间是如何通信的?

作者 | wingjay来源 | wingjay.com正常情况下,每个线程独立完成自己的任务就结束了,但某些特殊情况下,我们需要多个线程来共同完成某项任务,这时就涉及到了线程间通信了。本文涉及到的知识点:thread.join()object.wait…

Linux debian解压和压缩.rar文件教程

一、简介 我们上传到Linux服务器上的文件日常是.zip或.tat.gz的文件,我们可以用相应的命令对文件进行解压。有时会遇到.rar文件。本次使用rar软件版本是5.6.0。官方网站为http://www.rarlab.com/ 二、下载和安装rar文件 1.创建文件夹 [rootdoudou ~]# mkdir /us…

windos手工扩展分区

为什么80%的码农都做不了架构师?>>> windows 2003系统下手工扩展分区(2008系统直接在磁盘管理里扩展卷即可) 1、虚拟机关机,将目标磁盘扩展到所需大小 2、开机,进入命令行模式 3、diskpart 进入diskpart工…

面试突击 | 彻底搞定 JVM 这几道高频面试题

前言 Java 相比 C/C 最显著的特点便是引入了自动垃圾回收 (下文统一用 GC 指代自动垃圾回收),它解决了 C/C 最令人头疼的内存管理问题,让程序员专注于程序本身,不用关心内存回收这些恼人的问题,这也是 Java 能大行其道的重要原因之…

阿里面试官给你的一些忠告,这样做肯定错不了!附视频

作者 | 梦游的龙猫来源 | http://dwz.win/2pU近期面试了许多,真的是许多同学,讲道理其实我是比较有耐心的面试官,但是还是忍不住想要吐槽,因此写下这篇文章,一方面希望可以帮助到正在面试,或者在来面试路上…

Java面试详解(2020版):500+ 面试题和核心知识点详解

与其在网上拼命的找面试题,不如加入我们畅快的阅读。为了写好这些面试题,我先后拜访了一二十家互联网公司,与不同的面试官和面试者进行面对面探讨,深入了解了企业对于面试者的要求和常见的 Java 面试题型。之后我花了大半年的时间…

Linux debian安装Vim和Vim使用教程

Vim 是一个开源免费工具,具有命令行界面和图形用户界面。它对于编辑用 shell、python、Perl、c/c 等编写的配置文件和程序特别有用。最新版本的 Vim 包括一些新功能、错误修复和文档更新。 Vim安装步骤 步骤一、首先使用下面命令更新一下系统,确保您的…

给所有开发人员的 11 条忠告(第 4 条亮了)

1、初学者尽量去有成熟技术团队的公司 其实很多小型的互联网创业公司只有一两个人技术人员,如果里面有大牛能带你成长还好,但大部分估计都是要你自己去摸索学习来解决公司的问题,对个人成长其实是很慢长对过程,相反如果你去大厂&a…

Linux debian安装Notepadqq,Linux系统下的Notepad++编辑器

Notepad是Windows系统常用的文本编辑器,而Notepadqq是Linux系统下Notepad的免费开源替代品。 在Debian系统中安装Notepadqq的方法 Debian也可以像Ubuntu系统一样使用PPA来安装Notepadqq,但我们需要手动添加PPA。 1.打开终端,使用以下命令&…

Codeforces Round #FF

A.DZY Loves Hash hash函数 h(x) x % p  输出第一次冲突的位置 #include<iostream> #include<cstdio> #include<cstdlib>using namespace std;const int maxn 4000;int p, n; bool inhash[maxn];int main() {freopen("447A.in", "r"…

面试突击 | Redis 如何从海量数据中查询出某一个 Key?视频版

作者 | 王磊面试突击 | 第 001 期1 考察知识点本题考察的知识点有以下几个&#xff1a;Keys 和 Scan 的区别Keys 查询的缺点Scan 如何使用&#xff1f;Scan 查询的特点2 解答思路 Keys 查询存在的问题Scan 的使用Scan 的特点3 Keys 使用相关 1&#xff09;Keys 用法如下2&#…

面经 | 我是如何拿到阿里offer的?附面试题+视频

作者 | rhwayfunn来源 | http://dwz.win/2JK本文来自 rhwayfunn 本人自述&#xff1a;拿到阿里实习offer&#xff0c;经历了5次面试&#xff0c;其中4轮技术面&#xff0c;1轮HR面试。在这里分享一下自己的面试经验和学习总结。希望能够帮助更多的小伙伴。我本科毕业于中南大学…

SCOM 2012知识分享-9:配置警报解决状态

适应平台&#xff1a;System Center 2012 RTM/SP1-------------------------------------------------------------------------------------------------------------设置警报的解决状态在操作控制台中&#xff0c;请单击监视。单击任何视图&#xff0c;将显示警告&#xff0c…

Linux debian ubuntu安装GIMP软件

一、GIMP简介 名称由GNU Image Manipulation Program&#xff08;GNU图像处理程序&#xff09;的首字母组成&#xff0c;是一个自由及开放原始码的点阵图图像编辑器&#xff0c;用于图像照片润饰及编辑、自由绘图、调整大小、裁剪、相片蒙太奇、装换图像格式以及其他专业任务。…

面试突击 002 | Redis 是如何处理已过期元素的?

1 面试题 Redis 如何处理已过期的元素&#xff1f;2 涉及知识点 此问题涉及以下知识点&#xff1a;过期删除策略有哪些&#xff1f;这些过期策略有哪些优缺点&#xff1f;Redis 使用的是什么过期策略&#xff1f;Redis 是如何优化和执行过期策略的&#xff1f;3 答案 常见的过期…

Linux debian安装PyCharm教程、配置pyqt5开发环境

一、PyCharm下载 首先需要下载一个PyCharm社区版压缩包&#xff1a;pycharm-community-2021.1.3.tar.gz。 Linux PyCharm社区版下载 二、PyCharm安装 1.我们最好在普通用户下解压并启动这个软件。如果你在超级用户下启动&#xff0c;你的pycharm就不能输入中文了&#xff0c…

10大iOS开发者最喜爱的类库

该10大iOS开发者最喜爱的库由“iOS辅导团队”成员Marcelo Fabri组织投票选举而得&#xff0c;参与者包括开发者团队&#xff0c;iOS辅导团队以及行业嘉宾。每个团队都要根据以下规则选出五个最好的库&#xff1a;1&#xff09;不能投自己写的库&#xff1b;2&#xff09;排除大…

面试突击第 3 期 | Redis 如何实现查询附近的人?视频实战版

这是我的第 33 篇原创文章作者 | 王磊 &#xff08;javacn666&#xff09;1 面试问题 Redis 如何实现查询附近的人&#xff1f;2 相关面试问题 Redis 中如何操作位置信息&#xff1f;GEO 底层是如何实现的&#xff1f;如何在程序实现查询附近的人&#xff1f;在实际使用中需要注…

Linux debian ubuntu的PyCharm无法正常输入中文

debian ubuntu中 PyCharm 当全拼输入2~3个汉字时&#xff0c;会被强行打断&#xff0c;然后就无法继续输入(也无法切换中英文)&#xff0c;并且汉字下会有下划线。 解决方案&#xff1a; 1.点击PyCharm菜单 “Help ->Edit Custom VM options…” 2.添加 -Drecreate.x11.in…