在 Golang 语言项目开发中,为了更加方便操作 MySQL,我们通常会选择开源 ORM,但是社区有很多 ORM,可能在项目后期会遇到更换 ORM 的需求,我们可以使用接口使 ORM 尽量少的侵入业务代码,为以后替换 ORM 做准备。

type DBOrm interface {
 Insert(param ...interface{})
}

type XormDB struct {
 db *xorm.Session
}
func (x *XormDB) Insert(param ...interface{}) {
 _, err := x.db.Insert(param)
 if err != nil {
  log.Println(err)
 }
}

// type GormDB struct {
//  db *gorm.DB
// }
// 
// func (g *GormDB) Insert(param ...interface{}) {
//  g.db.Create(param)
// }

type User struct {
 orm DBOrm
 Id int64
 Name string
}

func (u *User) DB() DBOrm{
 u.orm = new(XormDB) // 数据库实例注入接口
 // u.orm = new(GormDB)
 return u.orm
}

func TestOrm(t *testing.T) {
 user1 := new(User)
 user1.Name = "lucy"
 user1.DB().Insert(user1)
}
阅读上面这段代码,我们创建了一个接口 DBOrm,创建了两个 ORM 结构体,并分别实现了接口 DBOrm 的签名方法,在业务结构体 User 中,包含的不是某个 ORM 结构体,而是 DBOrm 接口。

ps:上面的代码摘自公众号:https://mp.weixin.qq.com/s/VANSVcLtCLC0gWmEsa8sFw
是golang接口编程的一个demo

可以看出这里借助了实现类与具体接口的关系,可以是大部分业务不依赖具体实现,但是实际上业务还是依赖具体接口的,需要修改业务代码u.orm = new(XormDB),这一步还是需要侵入业务代码的,如果想完全脱离手动可以使用wire等依赖自动管理依赖注入