如何实现数据层的Golang接口

问题描述 投票:0回答:1

我正在学习Golang并尝试学习一些好的实践。我看了这个视频:https://www.youtube.com/watch?v=EqniGcAijDI,在 8:45 左右,他开始实现数据存储层的接口。

我理解接口允许业务层和技术层解耦,这将使更改数据库引擎等变得更容易。

我不明白的是我应该在该接口上实现哪个方法?

在视频中他添加了一个非常具体的方法:

Get(int) *types.User

因此,每个实现该接口的存储都必须有一个 Get 方法,该方法返回指向用户的指针。

那么,我应该在我的存储接口中添加我数据库所有对象的所有方法吗?

我错过了什么吗?

谢谢!

database go interface orm
1个回答
0
投票

是的,你知道。它不是关于应该实现接口的模型,而是关于数据访问层。

他展示的示例相当简单:

type Storage interface {
  Get(int) *types.User
}

假设你这样使用它:

// GetUser returns a http.Handler which uses a Storage.
// It does not care whether it is backed by a DB, files
// or any other means of storage (say a map[int] *types.User for testing),
// all it cares about that it will get a user if it calls store.GetUser(int).
// Or a mock, for that matter, which makes testing the handler
// **MUCH** easier.
func Getuser(store Storage) http.Handler {

  // Most of error handling omitted for brevity
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
     idParam := r.URL.Query().Get("cur1")
     id,_ := strconv.Atoi(idParam)

     user := store.Get(id)
     if user == nil {
       http.Error(w,"user not found", http.StatusNotFound)
       return
     }
     json.NewEncoder(w).Encode(user)
  })
}

现在,只要您的数据访问层实现了

Storage
,您就可以轻松切换您正在使用的实际数据库,而无需在处理程序中更改一行代码。

显然,这只是开始。

旁注:我也不同意界面的设计,而且非常强烈。我的典型界面是这样的


// UserRepository is the data access layer for users.
// And yes, I come from Java... ;)
type UserCrudRepository interface {

   // Create unsurprisingly persists a user.
   // Since an ID might be created or a `create|modified_at`
   // field populated, we return the newly created user.
   // We also return an error which lets us decide on how to deal
   // with the problem. Say `ErrUserAlreadyExists`... You get the picture.
   Create(*types.User)(*types.User, error)

   // Get should be self-explanatory.
   Get(int) (*types.User, error)
   // List too.
   List() ([]*types.User, error)

   // Update returns the newly modified user
   // for pretty much the same reasons as in Get.
   Update(*types.User) (*types.User, error)

   // Delete deletes a user from the persistence.
   Delete(int) error

   // Sometimes, it might be necessary to delete more
   // than one user. Instead of iterating and execute many operations,
   // we can wrap this in a single transaction for databases, for example.
   // Or, you can make it a convenience method around
   //
   //   for _, id := range ids {
   //      if err := Delete(int); err != nil {
   //        // Handle error
   //      }
   //   }
   //
   // for more simplistic stores
   DeleteBulk(ids []int) error
}
© www.soinside.com 2019 - 2024. All rights reserved.