Designing and Placing Interfaces
Swipe to show menu
When designing interfaces in Go, you should pay careful attention to their size, naming, and placement. Small, focused interfaces are easier to implement and test. For example, an interface with a single method is often more useful than a large interface with many unrelated methods. Naming should clearly communicate the purpose of the interface, often by describing a capability, such as Reader, Writer, or Logger.
Placement of interfaces is another important design consideration. Should you define your interface where it is implemented or where it is consumed? The answer often depends on your project’s structure and goals, but Go idioms favor defining interfaces on the consumer side. This approach keeps interfaces minimal and tailored to the needs of the consuming package, which increases flexibility and decouples your code from specific implementations.
consumer/logger.go
provider/simplelogger.go
main.go
1234567891011package consumer // Logger is defined in the consumer package. type Logger interface { Log(message string) } // DoWork uses a Logger to log messages. func DoWork(l Logger) { l.Log("Doing some work...") }
Defining interfaces where they are used, rather than where they are implemented, has several advantages. It allows you to specify exactly what behavior you need, without forcing implementers to conform to a larger, less-focused interface. This results in code that is easier to test, mock, and refactor. When the consumer owns the interface, you can swap implementations freely, which increases the flexibility and maintainability of your codebase.
Thanks for your feedback!
Ask AI
Ask AI
Ask anything or try one of the suggested questions to begin our chat