Using go
and gorm
in a project.
I have created a dao
level to wrap the database operations, each table has its own dao type.
Get
method from FirstDao
for first
table and FirstModel
:
func (dao *FirstDao) Get(id uint64) (*model.FirstModel, error) {
}
Get
method from SecondDao
for second
table and SecondModel
:
func (dao *SecondDao) Get(id uint64) (*model.SecondModel, error) {
}
Wondering is it possible to write a BaseDao
in go, with a single Get()
method, so that I don't have to write this code 2 times.
This is very easy in Java, but since go is very different, and don't support real inheritance (I guess), not sure is this possible.
Get()
method, it still need an instance of the original specific struct, e.g model.FirstModel{}
, I pass it as interface model.Model
, and can't use it as original type.If you're trying to completely bypass writing a Get()
method for each DAO, your only solution is to return an interface{}
from this method.
However this approach creates two problems :
interface{}
everywhere.The solution I think the best, is to share most of the code by using structure embedding, and write lightweight wrappers for each DAO to convert the unsafe interface{}
into a type-safe value.
First create your base DAO with a generic Get()
method.
There is no type generics in Go, so you should return an interface{}
here.
type BaseDAO struct {}
func (*BaseDAO) Get(id uint64) (interface{}, error) {}
Then, for each type of data, create a specific DAO implementation, embedding BaseDAO
:
type FooModel = string
type FooDAO struct {
// Embbeding BaseDAO by not specifying a name on this field
// BaseDAO methods can be called from FooDAO instances
BaseDAO
}
func (foo *FooDAO) Get(id uint64) (FooModel, error) {
// Call the shared Get() method from BaseDAO.
// You can see this just like a `super.Get()` call in Java.
result, _ := foo.BaseDAO.Get(id)
return result.(FooModel), nil
}