英文:
Model responsibility vs Generic Function
问题
我们有一个用go
语言编写的MVC应用程序。
有两个端点,看起来是查询数据库以获取所有相关用户的。
/get_paginate_users - > 使用分页端点查询数据库
/get_users - > [1, 2] - > 使用给定的ID查询数据库。
为了实现通用功能,我将驱动程序选项作为参数传递给模型函数。
// controller.go
// # /get_paginate_users
models.FindUsers(bson.M{}, options.Find().SetLimit(limit))
// bson.M {} 和 options.Find() 是特定于驱动程序的参数(在我们的情况下是mongodb)。
// controller.go
// # /get_users
models.FindUsers(bson.M{user_ids: bson.M{"$in": user_ids}}, nil)
这就是我与同事讨论的地方,他认为像bson.M
这样的与数据库相关的内容应该只在模型中存在。(因为将来如果更改数据库,就需要在多个地方进行更改)
但这样做会导致非通用的函数。
在这种情况下,应该做什么是理想的?是实现通用函数还是让模型处理所有驱动程序的数据类型?
英文:
We have MVC application written in go
lang
There are 2 endpoint that looks to query database to get all relevant users.
/get_paginate_users - > Query Database with paginate endpoint
/get_users -> [1, 2] -> Query Database with given ID.
To the sake of achieving generic functionality I'm passing the Driver options as the parameters to models function.
// controller.go
// # /get_paginate_users
models.FindUsers(bson.M{}, options.Find().SetLimit(limit))
// bson.M {} and options.Find() are driver specific argument (in our case mongodb).
// controller.go
// # /get_users
models.FindUsers(bson.M{user_ids: bson.M{"$in": user_ids}}, nil)
This where I'm having a discussion with my colleague, He is of the opinion that database related stuff like bson.M
should only the part model. (Since In future if the database is changes it would require change in multiple places)
But doing so result in non generic functions.
What is ideal thing to do over here?, Having to achieve generic function or have model deal with all the driver data type?
答案1
得分: 2
这听起来像是一个明显的单一职责原则的例子。
控制器不应该关心你使用的数据库的实现细节。如果你要切换到另一个数据库,只有数据库逻辑应该改变,控制器不应该改变。
你可能想看一下六边形架构。不过可能有点过头了。
理想情况下,你应该通过接口隐藏数据库的实现细节。例如:
type UserRepository interface {
FindUser(ctx context.Content, id int) (User, error)
FindUsersByString(ctx context.Context, s string) (User, error)
// 等等...
}
然后你可以使用MongoDB或其他数据库来实现它。控制器应该有一个成员变量userRepo UserRepo
。
英文:
This sounds like a clear cut example of the Single responsibility Principe
The Controller shouldn't bother with the implementation details of the database you are using. If you were to switch to another DB, only the DB logic should change. The controller should not.
You might want to take a look at the Hexagonal Architecture. Though that might be overkill.
Ideally you would hide the implementation details of the database behind an interface. e.g.:
type UserRepository interface {
FindUser(ctx context.Content, id int) User, error
FindUsersByString(ctx context.Context, s string) User, error
// etc...
}
Which you can them implement with MongoDB, or another DB. The Controller should then have a member userRepo UserRepo
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论