Go 戈朗码构造
是否值得在结构中对方法进行分组: 例如:Go 戈朗码构造,go,Go,是否值得在结构中对方法进行分组: 例如: type UserManager struct { DB *sql.DB } func (m UserManager) Insert (u User) error {...} func (m UserManager) Delete (u User) error {...} ... 或者更简单,只支持单独的功能 func InsertUser (u User, db *sql.DB) error {...} 虽然第二种方法一开始看起来更简单,
type UserManager struct {
DB *sql.DB
}
func (m UserManager) Insert (u User) error {...}
func (m UserManager) Delete (u User) error {...}
...
或者更简单,只支持单独的功能
func InsertUser (u User, db *sql.DB) error {...}
虽然第二种方法一开始看起来更简单,但在将来这种方式下,包中可能会有很多函数。我应该为每个域聚合制作单独的包吗?在示例中,我已经看到了目前为止,只有model
package。
我主要使用OO语言,因此需要一些关于go最佳实践的建议。您的第二个建议不是好的go代码!为什么?因为在最好的情况下,函数应该将接口作为输入 因此,
InsertUser
函数应该是这样的,它将结合您的第一个建议和第二个建议:
type Inserter interface {
Insert(User)error
}
func InsertUser(i Inserter) error {...}
在这种情况下,测试函数很容易,因为您可以轻松地模拟插入器。或者两者都不做-在我看来,这并不重要,因为惯用的方法是使用接口组织这些概念:
package user
type User ...
type Inserter interface { Insert(User) error }
type Deleter interface { Delete(User) error }
type Manager interface { Inserter, Deleter } // bloated interface
User
在本例中可能是一个具体的行类型,如您的示例中所示,但也可以将其制作成一个不提及这些类型的界面
如果您编写引用这些接口的函数,那么您可以使用
在您的案例中,很明显,坚持第一种实现风格要简单得多:
type userManager struct { ... }
func (userManager) Insert(u User) error { ... }
func (userManager) Delete(u User) error { ... }
userManager
是一种私有类型,因此只要它满足公共接口的要求,就可以随意更改它
保持接口与实现的解耦,可以更容易地缩小它们的范围,因此您可以找到任务真正需要的接口,而不仅仅是“用户管理器”之类的东西。顺便说一句,这种方法有一个很好的特性,它非常适合,这有助于简化基于角色的访问控制。我建议使用第一种方法。它使代码库更加结构化,可读性更强。通过创建一个实例或UserManager,在编写代码时,可以在其上完成的所有应用程序都将非常清晰。我喜欢这个答案与我试图表达的观点相同,但角度非常不同。我认为这充分说明了基于界面的设计可以多么强大地融合在一起,我认为这才是围棋的真正魅力所在