codecamp

GoFrame 工程开发设计-代码分层设计

代码分层的意义在于将程序逻辑进一步解耦,将层级之间的数据流和依赖关系设计为单向链路,使得系统架构更加灵活易扩展。

一、基本介绍

GoFrame​作为一款工程化完备的基础开发框架,有其独特的框架设计理念,这一章节我们来介绍一下她的代码分层设计。对于服务端业务代码的分层设计模式中,我们比较常见的是​MVC​设计模式和三层架构设计模式(​3-Tier Architecture​)

二、MVC设计模式

我们先来回顾一下经典的​MVC​设计模式。

image2021-1-5_0-4-8

简要介绍

M​代表模型(​Model​),表示业务规则封装。在​MVC​的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。

V​代表视图(​View​),用户看到并与之交互的界面。比如由​HTML​元素组成的网页界面,或者软件的客户端界面。​MVC​的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操纵的方式。

C​代表控制器(​Controller​),接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。

这种设计模式比较简单,比较合适于需要服务端渲染页面的业务场景,对于​SEO​来说也比较友好。但随着​MVVM​开发模式的兴起,以及前端技术的快速发展,特别是一些前端开发框架如​Vue​、​React​、​Angular​之类的项目出现,服务端的​MVC​设计模式使用场景变得越来越少。

痛点描述

针对于业务逻辑并不是特别复杂的业务场景项目,​MVC​还能游刃有余,但随着业务逻辑变得庞大复杂,​MVC​设计模式的项目维护成本上升的问题变得越来越明显。特别是随着互联网项目微服务架构的发展,​MVC​设计模式在大部分的互联网项目开发中变得越来越鸡肋。究其原因,主要的几点:

  • 视图展示与数据操作方式的进一步剥离,特别是移动端的发展,前端​MVVM​框架的发展,我们大多数场景下已不再需要服务端渲染​View​。
  • MVC​的代码分层设计模式其实粒度较粗:
    • Model​层级的代码既维护着数据,也封装着业务逻辑,随着业务逻辑变得越来越复杂,这一层功能逻辑会变得越来越臃肿不易维护。
    • 对于团队管理来讲,​Controller​和​Model​的职责边界比较模糊,很难保证参差不齐的团队成员能够清晰地认识到​Controller​层并不应当封装业务逻辑。对于开发人员写好代码的要求会比较高。

三、3-Tier Architecture

GoFrame​框架推荐的代码分层设计模式为三层架构设计(​3-Tier Architecture​)。三层架构设计能够很好地体现出软件设计"高内聚,低耦合"的设计思想。

image2021-1-5_1-0-5

传统的三层架构设计如上图,将项目代码划分了三层,每一层有其独自的职责边界。但在大多数的场景中,我们常看到的是以下的分层结构,将数据结构模型再进一步地抽离了出来统一维护。

image2021-1-5_0-52-35

表示层 - UI

User Interface​位于三层构架的最上层,与用户直接接触,主要是​B/S​中的 ​WEB​页面,也可以是​API​接口。表示层的主要功能是实现系统数据的传入与输出,在此过程中不需要借助逻辑判断操作就可以将数据传送到BLL系统中进行数据处理,处理后会将处理结果反馈到表示层中。换句话说,表示层就是实现用户界面/​API​接口功能,将用户的需求传达和反馈,并用​BLL​或者是​Model​进行调试,保证用户体验。

业务逻辑层 - BLL

Business Logic Layer​的功能是对具体问题进行逻辑判断与执行操作,接收到表现层​UI​的用户指令后,会连接数据访问层​DAL​,业务逻辑层在三层构架中位于表示层与数据层中间位置,同时也是表示层与数据层的桥梁,实现三层之间的数据连接和指令传达,可以对接收数据进行逻辑处理,实现数据的增删改查等功能,并将处理结果反馈到表示层​UI​中,实现软件功能。

数据访问层 - DAL

Data Access Layer​是数据库的主要操控系统,实现数据的增删改查等操作,并将操作结果反馈到业务逻辑层​BLL​。在实际运行的过程中,数据访问层没有逻辑判断能力,为了实现代码编写的严谨性,提高代码阅读程度,一般软件开发人员会在该层中实现通用数据能力进行封装(例如通过​ORM​组件)来保证数据访问层​DAL​数据处理功能。

模型定义层 - Model

模型定义也常用​Entity​实体对象来表示,主要用于数据库表的映射对象,在信息系统软件实际开发的过程中,要建立对象实例,将关系数据库表采用对象实体化的方式表现出来,辅助软件开发中对各个系统功能的控制与操作执行。建立实体类库,进而实现各个结构层的参数传输,提高代码的阅读性。从本质上看,实体类库主要服务于表示层、业务逻辑层以及数据访问层,在三层之间进行数据参数传输,强化数据表示的简约性。

需要注意区分的是,这里的​Model​和​MVC​设计模式中的​Model​虽然都是一个名字但是差别巨大,职责完全不同。

三层架构设计与MVC

由于​MVC​也是三层结构,因此有的同学也会将​MVC​笼统地归纳于三层架构设计中,从字面意义上来讲似乎也没什么问题。不过两者还是存在一定的区别。


可以看到,在三层架构设计中,​UI​表示层即相当于​MVC​的​View​和​Controller​层,原本在​MVC​中这两层的逻辑应当是比较"轻量"的,因此被合并为一层进行统一管理也可以理解。比较重要的一点是,原本​MVC​中的​Model​被拆分为了​BLL​和​DAL​,即将业务逻辑与数据访问进行分离,将原本臃肿的​Model​进行了进一步的解耦,有利于项目的更好维护。

软件架构的演变过程,特别是互联网软件架构的演变过程,本质也就是将业务逻辑不断解耦的过程。


GoFrame 框架设计-统一框架设计
GoFrame 工程开发设计-工程目录设计
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

GoFrame 核心组件

GoFrame 核心组件-数据库ORM

GoFrame 模块列表

GoFrame 模块列表-单元测试

GoFrame 模块列表-功能调试

GoFrame WEB服务开发

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }