【发布时间】:2020-06-22 05:10:22
【问题描述】:
感谢您花时间阅读这个问题!
我是 Golang 的新手,我一直在开发一个简单的社交媒体 API 来练习该语言。在这个项目中,我使用一个结构来表示用户发布的帖子的模型,如下所示:
// models/post.go
package models
import "time"
type Post struct {
ID uint64
Title string
Content string
AuthorID uint64
Likes uint64
CreatedAt time.Time
}
func (p *Post) ValidateFields() error {
// validate fields
}
可以借助存储库中的方法将这篇文章保存到数据库中:
// repositories/posts.go
import (
"database/sql"
"models"
)
type PostsRepository struct {
db *sql.DB
}
func NewPostsRepository(db *sql.DB) *PostsRepository {
return &PostsRepository{db}
}
func (r *PostsRepository) Save(models.Post) (uint64, error) {
// Passing the model as a parameter
}
如您所见,模型是作为参数传递的,这感觉像是一个问题,原因有两个:
- 我只需要三个字段即可将帖子保存到数据库(标题, 内容和 AuthorID),因为将生成其他所有内容 自动
- 如果我将单元测试写入 Save 函数,它将 依赖模型工作,因此模型有任何问题 会影响测试
因此,考虑到这一点,我考虑将参数从模型更改为接口,但由于接口只接受方法签名,在这种特定情况下,我只需要属性来将数据保存在数据库中,我认为它需要一个一些吸气剂,例如:
type PostInterface interface {
GetTitle() string
GetContent() string
GetAuthorID() uint64
}
(我知道将 getter 称为“GetAttribute”并不习惯,但这只是为了给您一个想法)
因此,我必须在我的 Post 模型上实现这三个方法,看起来像
func (p Post) GetTitle() string {
return p.Title
}
func (p Post) GetContent() string {
return p.Content
}
func (p Post) GetAuthorID() uint64 {
return p.AuthorID
}
这看起来不太好,但当我们去测试时,情况会变得更糟。 就像我说的,我不想在测试中使用模型,所以我必须创建一个结构作为存根或只有三个所需字段才能保存工作的东西(这听起来不错)。但是,我必须再次实现这三个方法,以便结构可以被 Save 函数接受为接口(这听起来很糟糕)
这听起来像是很多不必要的工作,有什么办法可以解决这个问题吗?我不确定我是否遗漏了有关 Go 的一些概念性内容,或者我的架构是否有任何可以解决此问题的更改,但我无法找到替代方案
谢谢!
【问题讨论】:
-
我在 1 中没有看到问题。在 2 中绝对没有。
-
@Volker 即使将来结构变得比我当前使用的字段大得多,也不会?我对此感到担忧,因为在我编写的其他语言中,最好只使用您实际需要的东西来使函数正常工作
-
预测一个可能存在也可能不存在的未来有点徒劳,正如您所说:其他语言并假设您在图表上有一个计算一些统计数据的算法但不使用让我们说边缘。您是否认为仅因为您有一个不需要节点的函数而仅将节点作为输入并将您的图形数据结构重写为边列表而编写该函数是“良好实践”?当然不是。
标签: go interface repository getter