原文地址:梁桂钊的博客前端
博客地址:blog.720ui.com数据库
欢迎转载,转载请注明做者及出处,谢谢!后端
分层思想,是应用系统最多见的一种架构模式,咱们会将系统横向切割,根据业务职责划分。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 三层架构只是概念层面的指导思想,咱们会将层次结构划分的更加细致。如今,咱们来深刻探讨“如何合理的设计代码分层,论代码分层的设计之道”。在笔者看来,合理的代码分层应该是这样的。如图所示。框架
那么,业务逻辑层 的职责是与__数据持久层__交互,对多个数据源的操做进行聚合,而且提供组合复用的能力。此外,它也是业务通用能力的处理层,其中还包括缓存方案、消息监听(MQ)、定时任务等等。此外,咱们要将尽量多的业务处理放在__业务逻辑层__,包括了参数校验、数据转换、异常处理等,而不是在 Controller 再去处理。前后端分离
笔者认为:请求处理层具备三块能力,一个是经过模板引擎渲染,例如 FreeMarket、Velocity 的页面渲染,以及经过 Controller 层封装的 RESTful API 的 HTTP 接口。若是项目中用到了 Dubbo、HSF、Thrift 等 RPC 服务,咱们还须要提供对于的服务给上游的业务方使用,它经过 Service 来实现并暴露成 RPC 接口。这里,Service 的命名是相对的,通常经过 Client 提供接口,经过 Service 实现具体的业务逻辑。微服务
咱们了解了逻辑结构,那么,笔者认为比较清晰的物理代码结构应该是这样的。ui
那么,咱们能够跨层级调用吗?笔者认为:咱们须要禁止跨层级调用,由于每一个层级都本身的职责,而且对上层而言是透明的,就像 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 时,统一封装成字符串。
总结一下,分层思想,将系统横向切割,根据业务职责划分。划分的目的是规划软件系统的逻辑结构便于开发维护。可是,随着微服务的演变和不一样研发的编码习惯,每每致使了代码分层不完全致使引入了“坏味道”。笔者试图提出一个新的代码分层思路来规避和规范这种分层结构。
若是你有不一样的想法和兴趣,欢迎加我微信一块儿探讨与交流哟~
(完,转载请注明做者及出处。)
更多精彩文章,尽在「服务端思惟」!