Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang multi-method interface and struct naming

Tags:

go

Golang docs provide a clear guidance on how to name single-method interface (by appending "-er"). But what is the best practice to name a multi-method interface that has only a single struct implementing it?

In C# the interface would have "I" prefix, in Java, the class will have "Impl" suffix. Are there similar guidelines for Golang?

The point of having an interface here is to be able to mock it for unit-testing of components that depend on it.

Here is a specific example of UserManager interface. It is going to be consumed by a web api controller that will translate HTTP requests into method calls on this interface. This web api controller will use most of the methods of 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? 

}
like image 923
alex Avatar asked Jul 16 '19 17:07

alex


People also ask

Can a struct have an interface GoLang?

The interface is a contract of implicit behaviors (object methods) you invoke as needed without the rigors of explicit declaration. These methods are then added onto user-defined structs to create an interface that is about behavior, not data.

How do you name an interface in GoLang?

Effective Go: Interface names: By convention, one-method interfaces are named by the method name plus an -er suffix or similar modification to construct an agent noun: Reader , Writer , Formatter , CloseNotifier etc. There are a number of such names and it's productive to honor them and the function names they capture.

How do you name a struct in GoLang?

For most cases the naming convention in Go is just to use camel case and start with upper case if it's a public field and lower case if it's not. But in words that are acronyms like API or URL they are written in full upper case eg. func ProxyURL(fixedURL *url.

How can a struct implement an interface?

A class or struct can implement multiple interfaces, but a class can only inherit from a single class. For more information about abstract classes, see Abstract and Sealed Classes and Class Members. Interfaces can contain instance methods, properties, events, indexers, or any combination of those four member types.


1 Answers

Coming from Java/C# to Go requires a paradigm shift.

Because they are implemented implicitly, interfaces are defined where they're consumed, not where they're implemented.

Because they're implemented implicitly, smaller interfaces are preferred over larger interfaces, hence the focus on single-method "Verber" interfaces. If you have a function that needs to read bytes, it can take a io.Reader, and the function can be supplied any type that has that method (regardless what other methods it has). You probably don't have a function that calls all 5 of the methods listed in your interface (if so, that function is probably doing too much).

If you feel like naming a struct and an interface the same thing and therefore need some kind of prefix/suffix, you're probably thinking about it the wrong way and might need to reconsider your design.

DBAL is one area where there is sometimes a real case for a larger interface (though it should probably still be composed of smaller interfaces). But in this case, "Impl" doesn't tell you anything - Java and C# love to have pointless interfaces, Go does not. If you'll only ever have one implementation, the interface is probably useless.

If you will have multiple implementations, the differences between them should guide your naming. For example, you might have a PostgresUserManager, a MongoUserManager, and a MockUserManager.

like image 172
Adrian Avatar answered Oct 18 '22 09:10

Adrian