译者:baiyutang
原文:https://bryanftan.medium.com/accept-interfaces-return-structs-in-go-d4cab29a301b
在这个文章中,我将试图解释 Golang “接受 Interfaces, 返回 Structs” 的思考过程。作为一名年轻的 Go 开发者,这是一直困扰我的事情。希望这篇文章能够帮助那些初学 Go 的人。
本文假设你对 Go 语法和接口已经很有初步的认识。
设定场景
生产者和消费者
├── db
│ └── db.go
└── user
└── user.go
复制代码
接受 Interfaces
让使用者定义它要使用的接口
让我们看一个例子
//db.go
package db
type Store struct {
db *sql.DB
}
func NewDB() *Store { ... } //func to initialise DB
func (s *Store) Insert(item interface{}) error { ... } //insert item
func (s *Store) Get(id int) error { ... } //get item by id
复制代码
db.go
只提供写入和读取的方法。
//user.go
package user
type UserStore interface {
Insert(item interface{}) error
Get(id int) error
}
type UserService struct {
store UserStore
}
// Accepting interface here!
func NewUserService(s UserStore) *UserService {
return &UserService{
store: s,
}
}
func (u *UserService) CreateUser() { ... }
func (u *UserService) RetrieveUser(id int) User { ... }
复制代码
返回 Structs
生产者返回具体类型
在这个例子中,NewDB()
返回具体的类型给消费者
//db.go
package db
type Store struct {
db *sql.DB
}
// returning concrete type here!
func NewDB() *Store { ... }
func (s *Store) Insert(item interface{}) error { ... }
func (s *Store) Get(id int) error { ... }
复制代码
反例
现在我们看到了好的例子,我们转向一个普遍容易犯的反向的模式。
//postgres.go
package db
type Store interface {
Insert(item interface{}) error
Get(id int) error
}
type MyStore struct {
db *sql.DB
}
func InitDB() Store { ... } //func to initialise DB
func (s *Store) Insert(item interface{}) error { ... } //insert item
func (s *Store) Get(id int) error { ... } //get item by id
//user.go
package user
type UserService struct {
store db.Store
}
func NewUserService(s db.Store) *UserService {
return &UserService{
store: s,
}
}
func (u *UserService) CreateUser() { ... }
func (u *UserService) RetrieveUser(id int) User { ... }
复制代码
总结
“接受 Interfaces
,返回 Structs
”,当你第一次听这个,可能听起来如此的不相关。但是,它可以归纳为这两个主要的概念:
让消费者定义他用到的 Interfaces
生产者应该返回一个具体的类型
附加资料
评论