goFrameV2 业务逻辑个人理解
相信很多刚刚入门golang开发的小伙伴跟我之前一样,不太能理解goFrame自动生成的demo项目下每个目录所代表的业务逻辑,不太能把业务代码和项目目录关联起来,这里我提供一点我自己的见解,帮助大家更快理解GF框架下,一个项目的搭建流程和代码逻辑。
首先,建议大家先看一下如下中阳哥的GoFrame入门视频教程
GoFrame项目实战
这是一个项目实战,建议大家浅看第2个视频就行,重点在于了解goFrame的业务逻辑。
如下是基于阳哥的项目架构,我个人对于这个架构的层级关系以及每一层要干什么事情的直观化表述以及到底什么叫所谓“goFrameV2实现的业务与数据解耦”,看完这些,也许能够打通懂代码但不懂项目的你入门golang开发的任督二脉。
-
项目架构个人理解
- dao层
- golang项目中对应底层数据库每张表sql语句的对应代码实现
- 一张表对应一个go文件,封装对应的CRUD操作
- 无需手写,定义好表结构通过gen dao命令直接生成
gf gen dao
- api层
- 定义request的结构体格式,即需要前端传回哪些数据
- 定义接收和返回报文的路径
- ( 这一步在前端完成 )客户端发出request请求后,html、css等解析报文抽取所需数据将其赋值给对应的结构体
- model层
- 定义后台真实存储数据的结构体格式,它的数据格式应当和api层定义的相照应(但是服务对象不同)
- 我的理解是api层服务于request对象而model层服务于数据库读写,方便数据保存
- logic层
- 定义一个 空结构体 和 以它为接收器 、以model层的结构体对象为形参的所有数据处理 方法
- 也就是定义了对于前端发回的处理请求和处理数据(由model层解读后)进行的操作
- 前端如何得知处理方法和处理数据:基于request提交的url最后两位(get、post)以及报文(post)
- 其操作结果往往是根据某个由model层定义的对应结构体对象通过dao层对数据库进行CRUD操作
- service层
- 由logic层对应模块自动生成,定义了一个由logic层对应模块下空结构体的方法集限制的接口(类型集)和一个该接口类型的本地实例化对象,但对象未初始化(即为nil)
- 另外实现两个 函数 分别实现本地该类型对象的注册和返回
- 简单说该层的作用是: 为能够使用logic层方法的接收器定义了一个接口以及该接口的一个空本地对象实例,并提供了一个该实例的注册与返回逻辑
- 请注意该对象实例是小写开头,所以只能通过函数被外包引用
- logic层与service层关联起来理解
- logic层的 init函数 中调用了 service层 实现的注册函数将service层的接口实例化为 logic层 实现的空结构体
-
这里是实现业务和数据解耦的一部分
- controller层
- 定义一个空结构体和以它为接收器、以api层的结构体对象为形参的所有数据处理方法,而且和logic层实现的方法完全重合, 所以该层和logic层的结构也是非常类似的(就和api与model层的关系一样)方法签名上只有形参的引用不一样,分别来源于api层和model层
- 该层每个方法中调用service层的实例返回函数(返回service层本地对象实例)的对应方法,这里的方法其实是logic层实现的,原因之后会讲。所以controller层就是接收api层定义的request对象将其转化为model对象,然后利用service提供的logic方法实现由前端request转到数据库CRUD操作,以相对安全和独立的方式(只调用了service层函数)串联业务层(前端request->api层)和数据层(model层->底层数据库)
-
实现业务和数据解耦的另一部分
- 对于刚刚抛出的问题:“这里的方法其实是logic层实现的”,我理解的过程是,项目启动时,已经执行了logic层的初始化操作(init函数),所以service层的本地接口对象已经初始化为logic层的对象,即接口对象的类型值已经设置为logic层的空结构体,所以尽管controller层的方法由该层定义的空结构体调用,但是底层实现数据库操作的是通过service层返回的本地实例在logic层实现的方法。
- 所以controller层承上启下的作用体现在它实现了api层到model层功能的传递。
- controller层补充
- 有人会问,controller层不是也引用了api和model层的内容吗?
- 是的,但是只是使用了其定义的结构体类型,用来格式化和传递参数,而没有调用这些层里的函数方法,并不构成事实上的逻辑耦合。从实现角度讲,即便其调用这些函数方法也同样可以实现业务逻辑,但我认为这样的操作模糊了controller层的业务定位,是不恰当的。
- 所以我认为,goFrameV2提出的业务数据解耦,实现方法之一就是controller层 仅通过 service层函数的调用实现业务逻辑和数据处理的传递,而api层和model层、controller和logic层不存在任何直接的互相内容引用。
- 注册路由,对外暴露接口、cmd.go
- 将controller层的空结构体与对应路由绑定,确定客户端访问服务器的对应路径,即访问该路径时,服务器自动解析域名,将对应的request请求通过前端语言解析为controller层的函数签名,并进行函数执行。
-
该步骤也许在前端完成,也许有后端的参与但是gf帮我们屏蔽了这个过程,我不是很确定。
- dao层