优秀的代码应该如何分层

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

一、背景

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

  1. 方便后续代码进行维护扩展;
  2. 分层的效果需要让整个团队都接受;
  3. 各个层职责边界清晰。

二、如何进行分层

2.1、阿里规范

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

  1. 开放接口层:可直接封装 Service 方法暴露成RPC接口;通过 Web 封装成 http 接口;进行 网关安全控制、流量控制等。
  2. 终端显示层:各个端的模板渲染并执行显示的层。
  3. Web 层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
  4. Service 层:相对具体的业务逻辑服务层。
  5. Manager 层:通用业务处理层,它有如下特征:
    1. 对第三方平台封装的层,预处理返回结果及转化异常信息;
    2. Service层通用能力的下沉,如缓存方案、中间件通用处理;
    3. DAO层交互,对多个DAO的组合复用。
  6. DAO 层:数据访问层,与底层 MySQLOraclePostgreSQL进行数据交互。

阿里巴巴规约中的分层比较清晰简单明了,但是描述得还是过于简单了,以及Service层和Manager层有很多同学还是有点分不清楚之间的关系,就导致了很多项目中根本没有Manager层的存在。下面介绍一下具体业务中应该如何实现分层。

2.2、优化分层

从我们的业务开发中总结了一个较为的理想模型:

  • 最上层ControllerTService是我们阿里分层规范里面的第一层:轻业务逻辑,参数校验,异常兜底。通常这种接口可以轻易更换接口类型,所以业务逻辑必须要轻,甚至不做具体逻辑。
  • Service:业务层,复用性较低,这里推荐每一个Controller方法都得对应一个Service,不要把业务编排放在Controller中去做,为什么呢?如果我们把业务编排放在Controller层去做的话,如果以后我们要接入其他框架,我们这里又需要把业务编排在做一次,这样会导致我们每接入一个入口层这个代码都得重新复制一份如下图所示:

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

  • Mannager:可复用逻辑层。这里的Mannager可以是单个服务的,比如我们的Cache,MQ等等,当然也可以是复合的,当你需要调用多个Mannager的时候,这个可以合为一个Mannager,比如逻辑上的连表查询等。如果是httpMannagerrpcMannager需要在这一层做一些数据转换。
  • DAO:数据库访问层。主要负责“操作数据库的某张表,映射到某个java对象”,Dao应该只允许自己的Service访问,其他Service要访问我的数据必须通过对应的Service

三、分层领域模型的转换

3.1、在阿里巴巴编码规约中领域模型

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

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

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

  1. 允许Service/Manager可以操作数据领域模型,对于这个层级来说,本来自己做的工作也是做的是业务逻辑处理和数据组装
  2. Controller/TService层的领域模型不允许传入DAO层,这样就不符合职责划分了。
    同理,不允许DAO层的数据传入到Controller/TService

四、关于包名的命名:

4.1、entitymodeldomain到底怎么用?

根据很多 Java 程序员的”经验”来看,一个数据库表则对应着一个 Domain 对象,所以很多程序员在写代码时,包名则使用:com.xxx.domain ,这样写好像已经成为了行业的一种约束,数据库映射对象就应该是 domain。但是你错了,domain 是一个领域对象,往往我们再做传统 Java 软件 Web 开发中,这些 domain 都是贫血模型,是没有行为的,或是没有足够的领域模型的行为的,所以,以这个理论来讲,这些 domain 都应该是一个普通的 entity 对象,并非领域对象,所以请把包名改为:com.xxx.entity

4.2、三句话总结下entitymodeldomain的不同:

  1. entity:必须和数据库字段一样
  2. model:前端需要什么我们就给什么
  3. domain:很少用,代表一个对象模块

五、总结

  1. 总的来说业务分层对于代码规范是比较重要,决定着以后的代码是否可复用,是否职责清晰,边界清晰。
  2. 当然这种分层其实见仁见智, 团队中的所有人的分层习惯也不同,所以很难权衡出一个标准的准则,总的来说只要满足职责逻辑清晰,后续维护容易,就是好的分层。

原文地址:https://www.cnblogs.com/vandusty/p/11409671.html

时间: 2024-10-08 07:48:01

优秀的代码应该如何分层的相关文章

何为优秀的代码

引言 优秀代码的评价标准是什么? 一直以来这个问题我都没认真思考过.今天刚好看到了一篇讨论该主体的文章,深有感触,特此记录一下自己的感悟. 结论 如果自己写的代码符合现阶段自己心中优秀代码的评价标准,那么就可以认为代码是优秀的.这里引出2个问题:1. 怎么定义自己心中优秀代码的标准:2. 为什么加入现阶段这个限定词. 问题1解答 俗话说:“一千个读者就有一千个哈姆雷特”,每个人对优秀代码的评价标准都不会完全相同.针对这个问题,我们可以把社会上被大部分人认可的标准来作为自己的评判依据,当然这些标准

优秀的代码的设计和组织架构

优秀的代码的设计和组织架构一块相同逻辑的代码在两处甚至多次用,就要考虑能否抽取到一处来,进行统一下:一个功能存在变数,就要考虑能否支持后续扩展,把变与不变抽取隔离,把变化的尽量可配置化:一块代码就执行一次,那么就要考虑是否要在启动的时候进行执行:一个实例就创建一个,那么就要考虑是否要在启动时直接通过单例模式提前创建好:只要存在网络调用,就一定要设置超时,这样异常时可以快速返回,保证服务的基本可用,不然都是耍流氓:如果开发的功能是一个工具(就是说按照工具的定位来开发的,那么就很容易知道哪些是变化的

优秀开源代码解读之JS与iOS Native Code互调的优雅实现方案

简介 本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge. 它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发送.接收.消息处理器的注册与调用以及设置消息处理的回调. 就像项目的名称一样,它是连接UIWebView和Javascript的bridge.在加入这个项目之后,他们之间的交互处理方式变得很友好. 在native code中跟UIWebView中的js交互的时候,像下面这样: [cpp] view

14款优秀的代码展示网站

本文列出的这些网站可以分享和展示你的代码.它们都提供在线预览功能,所以别人可以看到你的代码如何运行.它们有时候也被称作“代码广场”或者“沙箱”. 它们不仅仅提供简单的代码展示功能,还提供很多代码协作和实际编程过程会用到的功能.例如,当你需要别人帮你调试源代码的时候,可以使用这些网站分享你有问题的代码,然后把链接分享给帮助你的人.这使得他们可以方便的查看你的源代码并提供解决方案. 1.CodePen 在CodePen上,你可以演示被称作 pens 的代码.Pen 由 HTML.CSS和JS组成.C

前端优秀特效代码收集

不管是css3的还是js.jquery的 见到过的比较好且觉得有用的代码 1. 手机右上角圆角动画导航代码 2. jQuery背景可滑动的导航菜单代码

[译] 如何在React中写出更优秀的代码

目录 我们先来看 Linting 利用组件模块性.复用性和组合性 propTypes 和 defaultProps 知道何时创建新组件 组件 vs 纯组件 vs 无状态函数组件 无状态函数组件 纯组件 使用 React 开发工具 使用内联条件语句 尽可能使用代码片段库 React 本质 - 学习 React 是如何工作的 快速回顾 在React中写出更好代码的9条建议:学习关于 Linting, propTypes, PureComponent 等. Rajat S · 2018 年 4 月 1

如何编写优秀的代码?

前言:我只是在练习画 思维导图,提取一篇文章的重点 原文链接:http://news.cnblogs.com/n/549233/

这些优秀的主流代码编辑器,你用过多少款?

这些年来,编写代码本身已经成为一种艺术.现在,有大量的编程语言可供开发者选择使用,从汇编语言到 Ruby 和 Python.尽管对于给定的项目有许多编程语言可供选择,但有一件事是亘古不变的,每个开发者都需要一个代码编辑器来写代码. 一个好的代码编辑器不仅仅是一个简单的文本编辑工具,这是发生奇迹的地方,开发者编写的代码会转化为更大的项目的可用组件.鉴于这一重要性,难怪开发者会对与他们日夜共处的代码编辑器如此挑剔.每个开发者都希望拥有一个快速.易于使用且功能均衡的代码编辑器. 每个代码编辑器都会声称

编写优秀代码的10个技巧

作为程序员,写代码是需要一种崇高无上的精神来支撑的,写出优秀的代码,更需要你有深厚的底蕴和良好的编码习惯.在介绍写优秀代码的10个技巧之前,我们先来探讨一下什么样的代码才是优秀的代码. 稳定可靠(Robustness) 可维护且简洁(Maintainable and Simple Code) 高效(Fast) 简短(Small) 共享性(Reusable) 可测试性(Testable) 可移植性(Portable) 面对以上的目标,我们总结了以下10个写代码的技巧,希望对你有所帮助. 1.百家之