Go Gin 系列十三:优化应用结构和实现Redis缓存

Posted 脑子进煎鱼了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go Gin 系列十三:优化应用结构和实现Redis缓存相关的知识,希望对你有一定的参考价值。

前言

之前就在想,不少教程或示例的代码设计都是一步到位的(也没问题)

但实际操作的读者真的能够理解透彻为什么吗?左思右想,有了今天这一章的内容,我认为实际经历过一遍印象会更加深刻

本文目标

在本章节,将介绍以下功能的整理:

  • 抽离、分层业务逻辑:减轻 routers.go 内的 api 方法的逻辑(但本文暂不分层 repository,这块逻辑还不重)。
  • 增加容错性:对 gorm 的错误进行判断。
  • Redis 缓存:对获取数据类的接口增加缓存设置。
  • 减少重复冗余代码。

问题在哪?

在规划阶段我们发现了一个问题,这是目前的伪代码:

if ! HasErrors() { if ExistArticleByID(id) { DeleteArticle(id) code = e.SUCCESS } else { code = e.ERROR_NOT_EXIST_ARTICLE }} else { for _, err := range valid.Errors { logging.Info(err.Key, err.Message) }}
c.JSON(http.StatusOK, gin.H{ "code": code, "msg": e.GetMsg(code), "data": make(map[string]string),})

如果加上规划内的功能逻辑呢,伪代码会变成:

if ! HasErrors() { exists, err := ExistArticleByID(id) if err == nil { if exists { err = DeleteArticle(id) if err == nil { code = e.SUCCESS } else { code = e.ERROR_XXX } } else { code = e.ERROR_NOT_EXIST_ARTICLE } } else { code = e.ERROR_XXX }} else { for _, err := range valid.Errors { logging.Info(err.Key, err.Message) }}
c.JSON(http.StatusOK, gin.H{ "code": code, "msg": e.GetMsg(code), "data": make(map[string]string),})

如果缓存的逻辑也加进来,后面慢慢不断的迭代,岂不是会变成如下图一样?

image

现在我们发现了问题,应及时解决这个代码结构问题,同时把代码写的清晰、漂亮、易读易改也是一个重要指标

如何改?

在左耳朵耗子的文章中,这类代码被称为 “箭头型” 代码,有如下几个问题:

1、我的显示器不够宽,箭头型代码缩进太狠了,需要我来回拉水平滚动条,这让我在读代码的时候,相当的不舒服

2、除了宽度外还有长度,有的代码的 if-else 里的 if-else 里的 if-else 的代码太多,读到中间你都不知道中间的代码是经过了什么样的层层检查才来到这里的

总而言之,“箭头型代码”如果嵌套太多,代码太长的话,会相当容易让维护代码的人(包括自己)迷失在代码中,因为看到最内层的代码时,你已经不知道前面的那一层一层的条件判断是什么样的,代码是怎么运行到这里的,所以,箭头型代码是非常难以维护和 Debug 的。

简单的来说,就是让出错的代码先返回,前面把所有的错误判断全判断掉,然后就剩下的就是正常的代码了

(注意:本段引用自耗子哥的 如何重构“箭头型”代码,建议细细品尝)

落实

本项目将对既有代码进行优化和实现缓存,希望你习得方法并对其他地方也进行优化

第一步:完成 Redis 的基础设施建设(需要你先装好 Redis)

第二步:对现有代码进行拆解、分层(不会贴上具体步骤的代码,希望你能够实操一波,加深理解

以上是关于Go Gin 系列十三:优化应用结构和实现Redis缓存的主要内容,如果未能解决你的问题,请参考以下文章

煎鱼 Go Gin 系列十七:用Nginx部署Go应用

MATLAB应用实战系列(五十三)-模拟退火算法(附源码)

Go语言系列第三方框架和库——GIN:GIN介绍

使用Gin,MySQL和Docker开发博客(Part 1)

gin系列-模板引擎

Go使用Gin+Redis实现增删改查