Open geektutu opened 4 years ago
全是反射 看懵逼了 大佬真厉害
用MethodByName(method)实在太骚了,为什么不用interface,gorm的hook机制就是通过interface实现的
@shiluoye 嗯,这个地方使用接口的确更合适。判断是否实现了某个接口,实现了则调用。之前合入过一个 PR,ITableName
自定义表名的,如果实现了该接口,就使用 ITableName
返回的字符串作为表名。
@shiluoye 用MethodByName(method)实在太骚了,为什么不用interface,gorm的hook机制就是通过interface实现的
我的理解是:type IBeforeQuery interface { BeforeQuery(s *Session) error }
type IAfterQuery interface { AfterQuery(s *Session) error } ..... 等等
//然后修改CallMethod func (s *Session) CallMethod(method string, value interface{}) { ... if i, ok := dest.(IBeforQuery); ok == true { i. BeforeQuery(s) } ... return }
@feixintianxia 正解~
脱敏 desensitization ,比较敏感的信息,比如密码,在提交到服务器后,应该变为"**",从而保护隐私。此外,此类功能函数并未直接在包内定义,而是在调用时候定义,像"钩子"钓鱼一样,这里的鱼就是用户定义函数。
改成接口的话, 只需要对hook文件修改如下: 自测没问题, 我写的不够优雅, 有好的实现也请大家分享出来.
// Hooks constants
const (
BeforeQuery = "BeforeQuery"
AfterQuery = "AfterQuery"
BeforeUpdate = "BeforeUpdate"
AfterUpdate = "AfterUpdate"
BeforeDelete = "BeforeDelete"
AfterDelete = "AfterDelete"
BeforeInsert = "BeforeInsert"
AfterInsert = "AfterInsert"
)
type IAfterQuery interface {
AfterQuery(s *Session) error
}
type IBeforeInsert interface {
BeforeInsert(s *Session) error
}
// CallMethod calls the registered hooks
func (s *Session) CallMethod(method string, value interface{}) {
param := reflect.ValueOf(value)
switch method {
case AfterQuery:
if i, ok := param.Interface().(IAfterQuery); ok {
i.AfterQuery(s)
}
case BeforeInsert:
if i, ok := param.Interface().(IBeforeInsert); ok {
i.BeforeInsert(s)
}
default:
panic("unsupported hook method")
}
return
}
https://geektutu.com/post/geeorm-day5.html
7天用 Go语言/golang 从零实现 ORM 框架 GeeORM 教程(7 days implement golang object relational mapping framework from scratch tutorial),动手写 ORM 框架,参照 gorm, xorm 的实现。通过反射(reflect)获取结构体绑定的钩子(hooks),并调用;支持增删查改(CRUD)前后调用钩子。