分层思想,是应用系统最常见的一种架构模式,我们会将系统横向切割,根据业务职责划分。MVC 三层架构就是非常典型架构模式,划分的目的是规划软件系统的逻辑结构便于开发维护。MVC:英文即 Model-View-Controller,分成模型层、视图层、控制层。将页面和业务逻辑分离,提高应用的可扩展性及可维护性。如图所示。

事实上,MVC 三层架构只是概念层面的指导思想,我们会将层次结构划分的更加细致。例如,传统后端的 MVC 模式对于前后端的划分界限比较模糊。一般情况下,前端开发人员负责编写项目的静态页面,包括 HTML 页面、CSS 样式与 JavaScript 交互部分,并提供给服务端开发人员编写视图层业务,甚至有的项目直接让前端开发人员完成视图层的业务开发任务。这样的开发模式造成的问题在于,前后端在开发过程中分工不明确,并且存在相互强依赖,前端开发人员需要关心服务端的业务,服务端开发人员也需要依赖前端的进度。并且随着 Android、 IOS、 PC 以及 U3D 等多个客户端加入,程序的开发成本与维护成本会指数级上升。为了提高开发效率,细化职责,前后端分离的需求越来越被重视。前后端分离在于服务端提供 API 接口,前端调用 AJAX 实现数据交互。如图所示。

此外,随着数据存储能力的不断扩展(MySQL、Oracle、Redis、MongoDB、ElasticSearch、PostgreSQL、HBase 等),以及随着微服务的流行与普及,我们经常通过 RPC(Dubbo、HSF、Thrift 等)依赖很多外部接口或 HTTP 调用第三方平台。因此,我们需要一套细致划分的代码结构。此外,很多时候,我们在开发过程中,也并没有把它们职责划分开。例如,在代码结构中,我们将非常多的逻辑业务放在了 Controller 层,而只把 Service 作为数据透传的途径了。事实上,这个是不对的。无独有偶,我们还会发现有的项目中在 Dao 层调用远程服务,也有的会在 Service 层或者 Controller 层进行这样的操作,由于不同研发同学的习惯不同,或者偷工取巧导致开发代码风格完全不同,代码层次结构混乱。

总结一下,MVC 三层架构只是概念层面的指导思想,我们会将层次结构划分的更加细致。现在,我们来深入探讨“如何合理的设计代码分层,论代码分层的设计之道”。在笔者看来,合理的代码分层应该是这样的。如图所示。

其中,数据持久层 承载了数据存储和访问的能力,它既与底层数据进行交换,包括 MySQL、Oracle、Redis、MongoDB、ElasticSearch、PostgreSQL、HBase 等,又通过 Pxoxy 的代理和包装与远程服务数据进行联动。因此,在业务逻辑层调用时,它对底层的数据实现方式是无感知的,无论是哪种数据存储方式,以及它是远程数据,还是本地数据,都可以非常容易的调用。换句话说,我们需要将数据的查询和更改操作限制在数据持久层,并只能被业务逻辑层访问。

那么,业务逻辑层 的职责是与数据持久层交互,对多个数据源的操作进行聚合,并且提供组合复用的能力。此外,它也是业务通用能力的处理层,其中还包括缓存方案、消息监听(MQ)、定时任务等等。此外,我们要将尽可能多的业务处理放在业务逻辑层,包括了参数校验、数据转换、异常处理等,而不是在 Controller 再去处理。

笔者认为:请求处理层具有三块能力,一个是通过模板引擎渲染,例如 FreeMarket、Velocity 的页面渲染,以及通过 Controller 层封装的 RESTful API 的 HTTP 接口。如果项目中用到了 Dubbo、HSF、Thrift 等 RPC 服务,我们还需要提供对于的服务给上游的业务方使用,它通过 Service 来实现并暴露成 RPC 接口。这里,Service 的命名是相对的,一般通过 Client 提供接口,通过 Service 实现具体的业务逻辑。

我们了解了逻辑结构,那么,笔者认为比较清晰的物理代码结构应该是这样的。

那么,我们可以跨层级调用吗?笔者认为:我们需要禁止跨层级调用,因为每个层级都自己的职责,并且对上层而言是透明的,就像 OSI 七层协议模型和 TCP/IP 四层协议模型一样,只有将职责限制在自己的边界内,整体层次结构才清晰明了。那么对于同级调用,笔者认为在业务逻辑层是允许的,但是,要特别注意循环调用的产生。

现在,我们再横向理解几个领域模型:VO、BO、DO、DTO。这个概念,是由阿里编码规约提到的,由于其业务非常复杂,因此为了更好地进行领域建模和模型隔离,提出了这几个概念。其中,DO(Data Object)与数据库表结构一一对应,通过 DAO 层向上传输数据源对象。 而 DTO(Data Transfer Object)是远程调用对象,它是 RPC 服务提供的领域模型。注意的是,对于 DTO 一定要保证其序列化,实现 Serializable 接口,并显示提供 serialVersionUID,否则在反序列化时,如果 serialVersionUID 被修改,那么反序列化会失败。事实上,DO 和 DTO 唯一的区别在于,一个是本地数据源的领域模型,一个是远程服务的序列化领域模型。对于 BO(Business Object),它是业务逻辑层封装业务逻辑的对象,一般情况下,它是聚合了多个数据源的复合对象。那么,VO(View Object) 通常是请求处理层传输的对象,它通过 Spring 框架的转换后,往往是一个 JSON 对象。例如,你需要解决 Long 类型的数据精度丢失的问题(如果直接传给 Web 端的话,在 Long 长度大于 17 位时会出现精度丢失),你就可以在 Controller 层通过 @ResponseBody 将返回数据自动转换成 JSON 时,统一封装成字符串。

总结一下,分层思想,将系统横向切割,根据业务职责划分。划分的目的是规划软件系统的逻辑结构便于开发维护。但是,随着微服务的演变和不同研发的编码习惯,往往导致了代码分层不彻底导致引入了“坏味道”。笔者试图提出一个新的代码分层思路来规避和规范这种分层结构。

感谢大家,由于平台反馈多次链接会被和谐,需要免费的javaVIP资料和大厂面试题的可以+vwz100003备注头条 可直接进行复制添加哦,也可直接扫描下面二维码进行添加

https://u.wechat.com/MHq8lhOn7ngfzmOM_l45xPs (二维码自动识别)

mvc三层架构_Java架构-代码分层的设计之道相关推荐

  1. service 层 拼接的html 代码如何直接返回_代码分层的设计之道

    分层思想,是应用系统最常见的一种架构模式,我们会将系统横向切割,根据业务职责划分.MVC 三层架构就是非常典型架构模式,划分的目的是规划软件系统的逻辑结构便于开发维护.MVC:英文即 Model-Vi ...

  2. 3.设计模式之分层思维:为什么要做代码分层架构?

    一.代码分层架构是什么 软件程序通常有两个层面的需求: 功能性需求,简单来说,就是一个程序能为用户做些什么,比如,文件上传.查询数据等: 非功能性需求,这个是指除功能性需求以外的其他必要需求,比如,性 ...

  3. java三层 开源_java 山寨qq 聊天工具(基于mvc三层架构,附 mvc架构模式pdf说明文档)支持开源...

    [实例简介] java 山寨qq 聊天工具(基于mvc三层架构,附 mvc架构模式pdf说明文档)支持开源 [实例截图] [核心代码] java山寨qq聊天工具(基于mvc三层架构,附mvc架构模式p ...

  4. 阿里为什么建议给MVC三层架构多加一层Manager层?

    MVC三层架构 我们在刚刚成为程序员的时候,就会被前辈们 "教育" 说系统的设计要遵循 MVC(Model-View-Controller)架构.它将整体的系统分成了 Model( ...

  5. B站云E办Vue+SpringBoot前后端分离项目——MVC三层架构搭建后台项目

    本项目来源B站云E办,笔记整理了项目搭建的过程和涉及的知识点.对于学习来说,不是复制粘贴代码即可,要知其然知其所以然.希望我的笔记能为大家提供思路,也欢迎各位伙伴的指正. 项目前端学习笔记目录 B站云 ...

  6. Java中使用MVC三层架构做登陆验证

    这里主要的内容是有关Java中MVC三层架构 目录 原始的登陆验证 分层改进(每个代码都是登录和验证两个功能) 使用分层想法做登陆验证 User类 表现层 业务层 持久层 原始的登陆验证 原始的登陆验 ...

  7. JavaWeb之JSP和MVC三层架构

    JSP JSP概述 JSP的作用 JSP(全称:Java Server Pages):Java 服务端页面.是一种动态的网页技术,其中既可以定义 HTML.JS.CSS等静态内容,还可以定义 Java ...

  8. spring struts2 mybatis框架学习总结(mvc三层架构)

    spring struts2 mybatis框架学习总结(mvc三层架构) ssi的框架主要是由struts2,spring以及ibatis组成,他们负责各层之间的交互与协作,从而实现整个web端的功 ...

  9. 浅谈MVC三层架构(通俗易懂)

    "怕什么真理无穷,进一寸有一寸的欢喜"        ----胡适 什么是MVC三层架构? 所谓MVC三层架构,指的是Model View Controller,即模型.视图.控制 ...

最新文章

  1. 读书笔记-《增长黑客》-搭建增长团队
  2. Replication的犄角旮旯(五)--关于复制identity列
  3. iOS开发——UI基础-UIImage,UIImageView的使用
  4. Spring Boot怎么样注册Servlet三大组件[Servlet、Filter、Listener]
  5. uml -- unified modeling language 同一建模语言
  6. 挖矿主板bios设置_挖矿板的核心功能是什么?竟是“BIOS”
  7. xshess 要继续使用此程序,您必须应用最新的更新
  8. html翻译插件,翻译插件:ImTranslator
  9. sap税码配置_SAP那些事-技巧篇-42-Billing plan预收款税码问题
  10. 线程池系列三:动态修改线程池队列大小
  11. vue3子组件修改传值给父组件报警告warn:Component emitted event “update:dialogAddVisible”
  12. KILE5生成BIN文件的图文设置
  13. 小程序api(常用)
  14. 经典解压缩软件 WinRAR 5.71 无广告版
  15. 天文学论文绘图注意事项
  16. 软件工程应用与实践(1)——项目简介,小组分工
  17. jitter单位_JITTER
  18. Mysql偶尔连接失败的问题
  19. LAC+CELLID定位手机位置
  20. 权威发布|恭喜 Apache Doris PPMC 陈明雨入选 2021 中国开源先锋 33 人之心尖上的开源人物...

热门文章

  1. 人行征信报告(下)——探秘二代征信的内容
  2. API、H5跟风控相关的知识是否了解?
  3. Python入门学习笔记(3)
  4. 破碎纪念---记第二次Nexus4换屏
  5. SQLServer查询锁表
  6. welcome-file-list标签的控制作用以及在springmvc中此标签的的配置方式
  7. puppet 3+Unicorn+Nginx安装配置
  8. ASP.NET笔记(二)
  9. asp.net AJAX 验证用户名是否存在 -Jquery
  10. Jira项目导入,被导入项目与目的系统数据类型不一致导入不成功的解决方案