Golang多方法接口和结构命名

时间:2019-07-16 17:57:49

标签: go

Golang文档在how to name single-method interface上提供了清晰的指导(通过附加“ -er”)。但是,命名仅由一个结构实现的多方法接口的最佳实践是什么?

在C#中,该接口将具有“ I”前缀,在Java中,该类将具有“ Impl”后缀。 Golang是否有类似的指南?

这里有一个接口的目的是能够模拟它,以便对依赖于它的组件进行单元测试。

这是UserManager界面的特定示例。 Web api控制器将使用它,它将在此接口上将HTTP请求转换为方法调用。该Web API控制器将使用UserManager的大多数方法。

type UserManager interface { // Should it be UserManagerInterface ?
    GetUser(id int) User
    CreateUser(user User)
    DeleteUser(id int)
    ResetPassword(id int, newPassword string)
    VerifyEmail(id int)
}

type UserManagerImpl struct { // -Impl, or -Struct, or something else? 

}

2 个答案:

答案 0 :(得分:1)

从Java / C#转到Go需要进行范式转换。

因为它们是隐式实现的,所以在使用的位置而不是在实现的位置定义接口。

因为它们是隐式实现的,所以较小的接口比较大的接口更受青睐,因此,重点放在单方法“ Verber”接口上。如果您有一个需要读取字节的函数,则可能需要一个io.Reader,并且可以为该函数提供具有该方法的任何类型(无论它具有其他什么方法)。您可能没有一个函数可以调用界面中列出的所有5种方法(如果这样,则该函数可能做得太多)。

如果您想以相同的方式命名结构和接口,因此需要某种前缀/后缀,则可能是在考虑错误的方式,因此可能需要重新考虑设计。

DBAL是一个有时存在较大接口的真实情况的区域(尽管它可能仍应由较小接口组成)。但是在这种情况下,“ Impl”没有告诉您任何信息-Java和C#喜欢具有无意义的接口,而Go却没有。如果只有一种实现,则该接口可能无用。

如果您将有多个实现,则它们之间的差异将指导您的命名。例如,您可能有一个PostgresUserManager,一个MongoUserManager和一个MockUserManager

答案 1 :(得分:0)

您真的需要公开UserManagerImpl结构吗?有一个公共接口和相应的私有实现是很常见的。选中thisthis

type Store interface {
    RunRoot() string
    GraphRoot() string
    ...
}

type store struct {
    ...
}

func New() Store {
    return &store{}
}

func (s *store) RunRoot() string {
    return s.runRoot
}

func (s *store) GraphRoot() string {
    return s.graphRoot
}

我的意思是,如果您为接口想出了一个体面的名称,您仍然可以将其用于实现。但是总的来说,最好将其反映为真实的事物,而不管给定语言的最佳实践如何。项目是独一无二的,几乎不可能列出适合该语言所有用例的最佳实践。