大项目架构设计 | 青训营笔记

87 阅读3分钟

这是我参与「第五届青训营 」笔记创作活动的第8天。

前言

青训营的大项目需要组队完成,因此我写的代码不能像以前一样只要自己看得懂就行了,必须要有清晰的架构以便团队协作。不然每个人的代码都跟狗皮膏药一样往上贴,项目就真成屎山了。

项目架构

参考了go-clean-arch掘金视频课第四课的实现。 图片.png

图片.png

  • repository层负责与数据库和其他微服务进行交互,根据usecase层的请求返回查询到的model。这个model就是GORM中的“M”,可以理解为数据表的一行数据。
  • usecase层负责把查询到的model包装成entity。我个人的理解,entity就是借口文档里那些Video、User实体,但是由于一些原因无法直接用ORM存储到数据库里。比如说Video里面嵌套了一个User结构体用于记录用户信息,但是你数据库里不可能把User表嵌套进去,这样存储和更新的代价就太大了。所以只能记录user的id,usecase层根据视频id找video的model,然后根据里面的user id查到user的model,然后把两者组装一下返回。这一层不需要像另外两层一样做面向不同数据库、不同前端的各个模块,因为核心逻辑都是一样的;而且其输入输出也是固定的,是另外两层来适应它。
  • delivery负责对接前端,接受前端发来的请求,调用usecase层,再把得到的entity包装成响应体返回。
  • domain层定义了在其他三层里需要用到的各种结构体,即repository的Model、usecase层的Entity、delivery层的请求结构体与响应结构体;以及每一层要实现的接口。

文件结构

./src
|-- app //程序入口
|   `-- main.go
|-- basic //对应大项目基础接口(视频、用户)
|   |-- delivery //视图层
|   |   `-- http //web服务
|   |       |-- basic_handler.go //请求处理
|   |       `-- middleware //中间件,例如校验token
|   |           `-- middleware.go
|   |-- repository //数据层
|   |   `-- mysql //与mysql交互
|   |       `-- mysql_basic.go
|   `-- usecase //逻辑层
|       `-- basic_usecase.go
|-- config.json //配置文件
|-- domain //各种结构体、接口的定义
|   `-- basic.go
|-- go.mod
|-- go.sum
`-- public //存放静态文件

具体的文件结构如上所示。

  • app中是程序的入口
  • basic文件夹对应大项目三个模块之一,之后要写互动接口也再建一个文件夹。
    • delivery为视图层
      • http文件夹里实现了面向web前端的视图层函数(使用http协议)
        • middleware里是中间件
    • repository为数据层
      • mysql为与mysql数据库交互的部分
    • usecae为逻辑层。这里不需要再建文件夹了,因为无论前端和数据库是啥,处理逻辑都一样。
  • public里存静态文件,比如说视频和封面等。

优点

  • 可以轻松适配不同的数据库、前端,只需要编写repository或delivery层来对接即可。
  • 可以很方便的替换各种框架,比如要把gin替换成hertz只需要改repository层;不想用gorm了也只需要改repository层。
  • 便于协作,负责不同模块的同学只需要在src下新建自己模块的文件夹即可,不影响其他同学。
  • 便于调试,核心的usecase层用go自带的test单元测试即可,repository层可以用mock测试,delivery层可以用框架自带的测试工具。