OOP 好难啊.jpg

2019-09-28 23:51:50 +08:00
 bakabie

有几个数据库模型( Novel,Archives ),都是要增删改查的。用的是 Echo 框架。 本来想打算每个模型都对应一个请求模型,再 bind 到不同的 API。 即:

type NovelRequestGet struct{}
type NovelRequestDelete struct{}
...
type ArchiveRequestGet struct{}
type NovelRequestDelete struct{}
.....
echo.bind(&NovelRequest)
bind......

然后数据库操作一波,返回。

但是实际写的时候转念一想这不就是 CVM 嘛,除了传入变量类型不同其他代码完全一致。于是就用了 Interface。

type GetInterface interface {
	Get()*serializer.Response  //数据库查询操作
	Response() *serializer.Response //返回数据
}
func Get(service _interface.GetInterface)echo.HandlerFunc {
	return func(c echo.Context) (err error){
		if err := c.Bind(&service); err == nil {
			if err := service.Get(); err != nil {
				return c.JSON(200, err)
			} else {
				res := service.Response()
				return c.JSON(200, res)
			}
		} else {
			return c.JSON(200, &serializer.Response{
				Status: 40001,
				Msg:    "参数错误",
				Error:  fmt.Sprint(err),
			})
		}
	}
}

最后绑定路由

var ArchiveGet archive.GetService  
route.GET("/archive/:id", api.Get(&ArchiveGet))

这样本以为就可以实现泛型了,只要增删改查的业务就可以直接丢进来了。

然而,理想很美好,显示很骨干。

实际上运行

{
    "status": 40001,
    "data": null,
    "msg": "参数错误",
    "error": "code=400, message=binding element must be a struct"
}

还必须要转成 struct。。。

现在问题来了,请问各位老哥们:

  1. 我这样设计有错吗
  2. 如何解决目前这个问题

目前感觉唯一的解法似乎就是自己整一个反射然后再 Bind,但是感觉在这样弄一个 Interface{}的意义似乎就没有了?

请各位大佬解惑,小弟在此谢谢大家了

3583 次点击
所在节点    Go 编程语言
7 条回复
mcfog
2019-09-29 07:58:34 +08:00
云程序员来了!
首先我没用过 echo (略

golang 的 struct 不是 class,不要试图带入基于 class 的 oop 的范式

一般而言,要复用用组合,要多态用 interface,要封装分 package 用 unexported type/field 完事儿

//要泛型等 go2
janxin
2019-09-29 09:06:32 +08:00
你看,我就比较简单了,我就只会用

type NovelRequest struct{}
type ArchiveRequest struct{}
tairan2006
2019-09-29 09:28:00 +08:00
我也没用过 echo,不过我猜你应该这么设计:

根据`/archive/:id`中 id 绑定的具体参数,利用工厂模式生成不同的 struct。然后这些 struct 都实现了 interface,转换一下就行了,后面代码是一样的。
bakabie
2019-09-29 11:23:57 +08:00
@tairan2006 其实主要是工厂模式返回的 Struct 依旧是用 interface 返回出来的,而返回是 interface 的话,那个 bind 函数就用不了了
bakabie
2019-09-29 11:25:41 +08:00
@janxin 其实 xxxRequests 是必要有的,只是我想能不能省略一下 Bind。。毕竟每次 Bind 完的操作都是执行一样的函数,我就在想能不能只写一个 Bind,,,
bakabie
2019-09-29 11:29:30 +08:00
感谢诸位解惑。解决了。其实是我的锅。。把 Bind 中的&去掉就行了,我丢人了丢人了,快 TMD 溜。。。
popbones
2019-10-02 09:27:52 +08:00
grpc 了解下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/605196

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX