这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
前言
由于这次本人是第一次接触web开发,也是第一次开发这么大的项目,同时也是第一次与他人协作共同完成项目,所以对于有些内容的见解很使用不是十分到位,这次的笔记仅仅是个人的一次经历记录的心得体会,不一定具有参考学习价值。
项目介绍
这届的青训营大项目主要求是做出一个极简版抖音,官方也给了APP的说明文档的设计文档,最终要开发出来的APP其实就是实现了抖音的主要功能,如用户注册、登录、用户信息的查询、给视频点赞、评论、给用户关注等等。
我的工作
本次是一次小组协作开发,需要分工。由于我是第一次接触web开发和go语言,所以我的工作涉及到的是一些比较基础的开发,都是一些接口的代码实现,而对于架子的搭建、要使用的设计模式的选择以及数据库相关的工作是由我们的小组长完成。
实现背景
借助框架开发,不仅可以省去很多常用的封装带来的时间,也有助于团队的编码风格和形成规范。
gin框架
对于golang而言,web框架的依赖要远比Python,Java之类的要小。自身的net/http足够简单,性能也非常不错。
Gin是一个golang的微框架,封装比较优雅,API友好,源码注释比较明确,具有快速灵活,容错方便等特点。
gorm框架
ORM(对象关系映射): 把数据库映射成对象。ORM 使用对象,封装了数据库操作,因此可以不碰 SQL 语言。开发者只使用面向对象编程,与数据对象直接交互,不用关心底层数据库实现。
gorm是使用go语言实现数据库访问的ORM库。使用这个库,我们可以利用面向对象的方法,更加方便的对数据库中的数据进行CRUD(数据库的基本操作有四种:create、read、update和delete,简称 CRUD),而无需关心底层数据库的具体实现以及数据库的类型(支持多种类型的数据库,例如MySQL,SQLite,PostgreSQL,MSSQL)。
mvc软件架构模式
将软件系统分为了Handles、Service以及Models这三层。其中Handles层,负责转发请求,对请求进行处理,通俗来讲就是解析URL中的参数,调用下层的Service层的处理函数,以及返回前端的请求。Service层,负责对参数的校验,根据上层传来的参数调用Models层的底层数据库的增删改查,以及对Models层查询返回的数据、返回给Handels层信息的组装。Models层,负责对数据库的底层增删改查,返回给Service层查询数据。
实现的大致内容
1.用户信息
func UserInfoHandler(c *gin.Context) {
p := NewProxyUserInfo(c)
rawId, ok := c.Get("user_id")
if !ok {
p.UserInfoError("解析userId出错")
return
}
err := p.DoQueryUserInfoByUserId(rawId)
if err != nil {
p.UserInfoError(err.Error())
}
}
2.发布列表
func QueryVideoListHandler(c *gin.Context) {
p := NewProxyQueryVideoList(c)
rawId, ok := c.Get("user_id")
if !ok {
p.QueryVideoListError("解析userId出错")
return
}
err := p.DoQueryVideoListByUserId(rawId)
if err != nil {
p.QueryVideoListError(err.Error())
}
}
func (q *QueryVideoListByUserIdFlow) checkNum() error {
if !model.NewUserInfoDao().IsUserExistById(q.userId) {
return errors.New("用户不存在")
}
return nil
}
func (q *QueryVideoListByUserIdFlow) packDate() error {
err := model.NewVideoDao().QueryVideoListByUserId(q.userId, &q.videos)
if err != nil {
return err
}
var userInfo model.UserInfo
err = model.NewUserInfoDao().QueryUserInfoById(q.userId, &userInfo)
if err != nil {
return err
}
for i := range q.videos {
q.videos[i].Author = userInfo
q.videos[i].IsFavorite = model.NewVideoDao().IsUserFavorVideoExist(q.userId, q.videos[i].Id)
}
q.videoList = &List{Video: q.videos}
return nil
}
3.关注操作
func PostFollowHander(c *gin.Context) {
p := NewProxyPostFollow(c)
err := p.DoPostFollow()
if err != nil {
p.PostFollowError(err.Error())
return
}
p.PostFollowOk()
}
func (p *PostFollowFlow) checkNum() error {
isUserExist := model.NewUserInfoDao().IsUserExistById(p.followId)
if !isUserExist {
return ErrIvdFolUsr
}
if p.actionType != FOLLOW && p.actionType != CANCEL {
return ErrIvdAct
}
if p.userId == p.followId {
return ErrIvdAct
}
isFollowExist := model.NewUserInfoDao().IsFollowExist(p.userId, p.followId)
if p.actionType == CANCEL && !isFollowExist {
return ErrIvdDel
}
return nil
}
func (p *PostFollowFlow) publish() error {
var err error
switch p.actionType {
case FOLLOW:
err = model.NewUserInfoDao().AddUserFollow(p.userId, p.followId)
case CANCEL:
err = model.NewUserInfoDao().CancelUserFollow(p.userId, p.followId)
default:
return ErrIvdAct
}
return err
}
总结
在此次大项目的实践中,我学到了很多东西,包括go语言、go语言的web开发框架、团队协作的要求以及工具使用、软件设计模式的分层和计算机网络的知识。有了这次的项目实战经历,我对今后的发展更加有信心了。