为了让Go开发变得更简单我把传统多层结构改为准单层

前言

自从使用上Go语言我们把开发简单贯彻到底,一个语言是否用得到舒服吗,我们一方面是看语言本身,另一方面还得有个好用框架,我们开发项目一般是不会从零开始编写代码,都是找个框架,在框架基础上搭建自己业务。所以我们一直想有一个满足开发简单、维护简单、学习简单、性能优秀、安全保障的框架,全网搜索没有找到合意框架,经过7年积累,自己戳一个,目前使用已经满足快速开发外包项目要求了,新老程序员交接成本也很低。本文我们一起分享一下我们这赖人搭建的框架。

框架设计思路

我们包传统常见的表现层(Controller),业务逻辑层(Service),和数据访问层(DAO),压缩为仅1层即业务逻辑层,简称接口实现层。但我们框架是存在Controller层的,但开发时我们不会去写Controller层,Controller框架作为约束规则会自己生产,我们仅编写当前请求操作接口代码即可。 结构如下:

bash 复制代码
├── app                       # 应用目录
│   ├── douyinapp             # 抖音应用模块
│   │   ├── home              # 应用首页数据
│   │   ├── user              #抖音用户相关业务接口
│   │   └── controller.go    # 模块控制器-仅针对douyinapp控制
│   └── controller.go        # 总应用控制器

其中controller.go是控制,它控制使用模块,及模块控制它控制模块下的业务类使用。

控制层

1.主控控制代码如下,它是负责控制模块引入,也就是那个模块使用就在import引入,不用就去掉。

go 复制代码
package controller
 
/**
* app路由引入口《引入模块控制器》
*
* 请把您使用包用 _ "gofly/app/xx"导入您编写的包 自动生成路由
* 不需要使用的模块则注释掉 例如home模块暂时用不到就注释掉,这样不占用资源,使用是取消注释即可。
* 路由规则:包路径"business/article" + 包中结构体"Cate"转小写+方法名(首字母转小写_ "gofly/app/business"
* 有控制的模块请在RouterHandler添加模块的路由钩子
 */
import (
	"gofly/app/douyinapp"
	"gofly/utils/gf"
)
 
// 路由中间件/路由钩子
func RouterHandler(c *gf.GinCtx) {
	douyinapp.RouterHandler(c, gf.IsModelPath(c.FullPath(), "douyinapp"))
}

2.模块控制器代码如下,它是负责控制业务类引入,也就是那个业务类使用就在import引入,不用就去掉。

go 复制代码
package douyinapp
 
/**
* 引入控制器
* 请把您使用包用 _ "gofly/app/home/XX"导入您编写的包 自动生成路由
* 不是使用则注释掉
* 路由规则:包路径"home/article" + 包中结构体"Cate"转小写+方法名
 */
import (
	_ "gofly/app/douyinapp/home"
	_ "gofly/app/douyinapp/user"
	"gofly/utils/gf"
)
 
// 路由中间件/路由钩子,可以从c获取请求各种参数
func RouterHandler(c *gf.GinCtx, IsCtr bool) {
	if IsCtr {
		c.Next()
	}
}

接口实现层(业务逻辑层)代码实现

我们在接口实现层中编写,业务代码,在开发时我们只关心接口层,其他框架帮大家生成或自动引入无需人为编写,我们仅仅编写接口实现层代码,下面演示接口实现层代码编写步骤:

如下图,是home接口实现层代码,我们开发时就在douyinapp模块目录下添加业务类目录,然后在douyinapp目录的controller.go控制器import业务类,代码生成会自动引入。手动添加要自己用途一下。

1.添加业务类目录

如上图我们在douyinapp模块创建首页home类,我们直接创建名称为home文件夹即可

2.创建接口文件

创建接口有两种一种是接口忽略文件层路由则命名为index.go,生成路由/douyinapp/接口名。另一个是用文件名作为一层路由名称则命名:文件(字母或者字母+数字).go,这样生成路由为 /douyinapp/文件名/接口名。

以一种为例,我们创建index.go文件,添加一个获取首页轮播图数据,代码如下:

go 复制代码
package home
 
import "gofly/utils/gf"
 
/**
* 首页功能接口
 */
type Index struct{}
 
func init() {
	fpath := Index{}
	gf.Register(&fpath, fpath)
}
 
// 获取Swipe轮播数据
func (api *Index) GetSwipe(c *gf.GinCtx) {
	list := gf.List{gf.Map{"name": "第一页", "image": "https://weui.shanliwawa.top/weui/images/1.jpg"}, gf.Map{"name": "第2页", "image": "https://weui.shanliwawa.top/weui/images/2.jpg"}}
	gf.Success().SetMsg("获取Swipe轮播数据").SetData(list).Regin(c)
}

这样我们就编写好一个getSwipe接口,请求路由为:/douyinapp/home/getSwipe,如下图是框架自动生成路由,在终端打印日志。

总结

从上面我们可以看出编写一个接口很简单,代码很少,开发是我们也只关心业务接口,不用去几个文件编写代码,需要多个文件跳来跳去的。

如果你需要数据库操作,参考如下代码,直接在接口层编写,不用再写model层。

scss 复制代码
// 更新状态
func (api *Product) UpStatus(c *gf.GinCtx) {
	param, _ := gf.RequestParam(c)
	res2, err := gf.Model("createcode_product").Where("id", param["id"]).Data(gf.Map{"status": param["status"]}).Update()
	if err != nil {
		gf.Failed().SetMsg("更新失败!").SetData(err).Regin(c)
	} else {
		msg := "更新成功!"
		if res2 == nil {
			msg = "暂无数据更新"
		}
		gf.Success().SetMsg(msg).SetData(res2).Regin(c)
	}
}
 
// 删除
func (api *Product) Del(c *gf.GinCtx) {
	param, _ := gf.RequestParam(c)
	res2, err := gf.Model("createcode_product").WhereIn("id", param["ids"]).Delete()
	if err != nil {
		gf.Failed().SetMsg("删除失败").SetData(err).Regin(c)
	} else {
		gf.Success().SetMsg("删除成功!").SetData(res2).Regin(c)
	}
}
 
// 获取内容
func (api *Product) GetContent(c *gf.GinCtx) {
	id := c.DefaultQuery("id", "")
	if id == "" {
		gf.Failed().SetMsg("请传参数id").Regin(c)
	} else {
		data, err := gf.Model("createcode_product").Where("id", id).Find()
		if err != nil {
			gf.Failed().SetMsg("获取内容失败").SetData(err).Regin(c)
		} else {
			if data != nil && data["workerway"].String() != "" {
				data["workerway"] = gf.VarNew(gf.SplitAndStr(data["workerway"].String(), ","))
			}
			gf.Success().SetMsg("获取内容成功!").SetData(data).Regin(c)
		}
	}
}

感兴趣的朋友前往社区获取代码,有开源免费版和企业版根据情况自行选择:

goflys.cn/home

相关推荐
y先森21 分钟前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy21 分钟前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu108301891124 分钟前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿1 小时前
CSS查缺补漏(补充上一条)
前端·css
2401_857610032 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_2 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞2 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货2 小时前
Rust 的简介
开发语言·后端·rust
吃杠碰小鸡2 小时前
commitlint校验git提交信息
前端
monkey_meng3 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust