当前位置: 首页 > news >正文

PHP转Go很丝滑开发框架设计思路-把php优秀设计借鉴到Go框架设计里面-保留php开发习惯又能提供高软件性能

框架从以下设计要求使得达到有快速开发有又保证软件性能。框架要满足我们追求的大道至简、简单易容、减少开发者心智负担、快乐开发目标。

框架代码结构简单

框架设计的结构一定要简单,简单才能让新手容易上手、后续代码维护成本低、集成大项目才容易(不至于混乱)。目录结构如下,其中app目录使我们业务代码位置,app之外都是框架固定好的设计,开发时不用去动。app下每一个文件夹表示一个模块,如:admin、business后台管理接口,根据业务可以添加weixin、douyinapp等模块,让扩展变得简单。

同样的在模块内容也是可以添加文件夹表示一个业务类型,比如:在business模块下的文章(创建一个article文件夹),文章类也可能有文章管理、文章分类、文章评论,这些就在article文件夹里添加cate.go=编写文章分类接口,comments.go=编写文章评论接口,其他功能通用添加自己.go文件编写对应业务。

├── app                       # 应用目录
│   ├── admin                 # 后台管理应用模块(安装saas时存在、不安装则删除)
│   ├── business              # 业务端应用模块
│   ├── common                # 公共应用模块
│   └── controller.go         # 应用控制器
├── devsource                 # 开发静态资源(安装界面、代码生成模板)
├── resource                  # 静态资源及配置文件(发布应用带上)
├── runtime                   # 运行时文件(项目运行时自己生成)
├── utils                     # 框架核心代码及工具包
├── go.mod                    # 依赖包管理工具
├── go.sum         
├── main.go                   # main函数       
├── runner.conf               # fresh热编译配置文件
└── README.md                 # 项目介绍

后端路由可根据接口位置生成

从上面加粗例子创建的文章类,框架根据创建接口目录层级自行生产接口的请求地址并注册到服务上,比如:文章分类的获取分类列表、添加、删除,分别生成地址为:business/article/cate/getList、business/article/cate/save、business/article/cate/del。同样的评论也是一样的:business/article/comments/save,路径会根据它所在文件名生成。

为什么我们要把强调路由自动生成,因为Go的很多框架路由都是手动配置的,我们使用的Gin框架也是手动添加路由,为了避免手动添加工作量,自动生成还是很必要的,最重要的是,手动添加多人协同开发,可能存在填写一样的路由名,导致路由重复。根据目录和文件名生成避免重复,同时路可以更加api接口层级快速找到接口位置,方便通过接口找到代码,在后期维护即看其他人写代码也能快速定位代码位置。

orm操作链式操作习惯和php一样舒服

Go是强类型语言,在存取数据是需要对应数据字段类型去接收和提交数据。所以开发时需要写对应数据表数据结构,这个在开发时很费时,框架需要像php简单$变量很难做到。市面很多Go的ORM只有数据结构存取数据,每个操作都写数据表结构体很烦,所以我们框架一定集成一个需要要数据结构要求的ORM,当然我们集成的ORM是两者都兼容,这样习惯用结构的开发者也是可以使用结构,因为有些提供给其他人使用,有结构体的数据可以在取数据时候知道有哪些字段及数据类型。

看看我们数据数据库操作:

  • 获取全部数据
list, err := gf.Model("createcode_product_cate").Where("status",0).
Fields("id,name,status,createtime").Order("id asc").Select()
  • 保存数据
//添加数据有三种方法
//1.写入的数据中存在主键或者唯一索引时,返回失败,否则写入一条新数据
addId, err := gf.Model("createcode_product_cate").Data(param).InsertAndGetId()
//2.用于写入数据时并直接返回自增字段的ID
res, err := gf.Model("createcode_product_cate").Data(param).Insert()
//3.写入的数据中存在主键或者唯一索引时,更新原有数据,否则写入一条新数据
res, err := gf.Model("createcode_product_cate").Data(param).save()
  • 更新数据
res, err := gf.Model("createcode_product_cate").Data(param).Where("id", f_id).Update()
  • 删除数据
	res2, err := gf.Model("createcode_product_cate").Where("id", 1).Delete()

更多orm操作到:orm开发文档

开发一个接口示例:

package createcodeimport ("gofly/utils/gf"
)// 关联的分类
type Productcate struct{}func init() {fpath := Productcate{}gf.Register(&fpath, fpath)
}// 获取列表
func (api *Productcate) GetList(c *gf.GinCtx) {list, err := gf.Model("createcode_product_cate").Where("status", 0).Fields("id,name,status,createtime").Order("id asc").Select()if err != nil {gf.Failed().SetMsg(err.Error()).Regin(c)} else {gf.Success().SetMsg("获取列表").SetData(list).Regin(c)}
}// 更新状态
func (api *Productcate) UpStatus(c *gf.GinCtx) {param, _ := gf.RequestParam(c)res2, err := gf.Model("createcode_product_cate").Where("id", param["id"]).Data(param).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 *Productcate) Del(c *gf.GinCtx) {param, _ := gf.RequestParam(c)res2, err := gf.Model("createcode_product_cate").WhereIn("id", param["ids"]).Delete()if err != nil {gf.Failed().SetMsg("删除失败").SetData(err).Regin(c)} else {gf.Success().SetMsg("删除成功!").SetData(res2).Regin(c)}
}

现在web应用计划都采用前后端分离,所以只需保证后端开发接口速度快即可,前端不管那个语言可以使用vue、react等框架。我们框架基于Go语言简单基础上设计得让开发变得简单。我们使用过其他框架,有些参考java框架集成,还是集成过于重。我们还是喜欢大道至简这个设计思路,开发本来简单,写程序应该是一种享受,开发框架也是需要简单,不能增加开发者开发时的心里负担。

题外话这里引用他人一句话: Golang哲学就是"少便是多", 志在减少开发者的心智负担. 不过再好的语言也敌不过"人", 请接受Golang的风格 否则写出PHPGo, JavaGo真是作茧自缚。

我们大家喜欢Go,就是Go的设计者们初心就是为了减少开发者的心智负担。所以GoFly框架也是志在简洁简单、开发舒服、减少开发者心智负担。开发者朋友我们一起为快乐编程目标奋斗吧!我们在GoFly全栈开发社区等大家哦!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 主流的消息队列
  • Java语言的Springboot框架+云快充协议1.5+充电桩系统+新能源汽车充电桩系统源码
  • 极狐GitLab 17.4 升级指南
  • 2024年一区极光优化+分解+深度学习!VMD-PLO-Transformer-GRU多变量时间序列光伏功率预测
  • 研究生三年概括
  • 【实战篇】join语句怎么优化?
  • [leetcode]216_组合总和III_给定数字范围且输出无重复
  • uni-app - - - - - 实现锚点定位和滚动监听功能(滚动监听功能暂未添加,待后续更新)
  • 后端Java-SpringBoot整合MyBatisPlus步骤(超详细)
  • ubuntu下载安装部署docker,ubuntu下载最新的docker
  • vue3.0 + element plus 全局自定义指令:select滚动分页
  • 第一弹:llama.cpp编译
  • 4.5 了解大数据处理基本流程
  • EP33 评分接口和已评分状态
  • 2、.Net 前端框架:Blazor - .Net宣传系列文章
  • Create React App 使用
  • Effective Java 笔记(一)
  • HTTP中GET与POST的区别 99%的错误认识
  • MySQL几个简单SQL的优化
  • node学习系列之简单文件上传
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • use Google search engine
  • 从PHP迁移至Golang - 基础篇
  • 大快搜索数据爬虫技术实例安装教学篇
  • 大主子表关联的性能优化方法
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 基于游标的分页接口实现
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 驱动程序原理
  • 小程序测试方案初探
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 选择阿里云数据库HBase版十大理由
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #07【面试问题整理】嵌入式软件工程师
  • $.ajax()
  • (+4)2.2UML建模图
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (arch)linux 转换文件编码格式
  • (Java)【深基9.例1】选举学生会
  • (k8s中)docker netty OOM问题记录
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (十六)、把镜像推送到私有化 Docker 仓库
  • (图文详解)小程序AppID申请以及在Hbuilderx中运行
  • (转)负载均衡,回话保持,cookie
  • .gitignore文件使用
  • .NET 4.0中的泛型协变和反变
  • .net Stream篇(六)
  • .NET 分布式技术比较
  • @Documented注解的作用
  • [ C++ ] STL---string类的使用指南
  • [04] Android逐帧动画(一)
  • [2013][note]通过石墨烯调谐用于开关、传感的动态可重构Fano超——