When to Use Interfaces
Interfaces should be used in the following situations:
- Common behavior. For example,
sort.Interface
,io.Reader
that are used by multiple functions - Decoupling. Allows to use mocks in unit tests; use different algorithm without code changes
- Restricting behavior. Interface on the client side restricts the set of methods that can be called
As a general rule:
- We should create an interface when we need it, not when we foresee that we could need it
- We should accept interfaces and return structs
- Interfaces should be as small as possible, because the bigger the interface, the weaker the abstraction
Interface on the Producer Side Anti-Pattern
Interfaces generally should be created on the client side, not the producer side
Defining the interface on the producer side forces clients to depend on all the methods of the interface. Instead, the client should define the interface with only the methods it needs. This relates to the concept of the interface segregation principle, which states that no client should be forced to depend on methods it doesn’t use
Note that interfaces sometimes can be used on the producer side. For example, io
package exports interfaces because it also needs to export generic-use functions like io.Copy
:
func Copy(dst Writer, src Reader) (written int64, err error)
Returning Interface Anti-Pattern
In most cases we should return concrete implementations, not interfaces
Returning concrete types means that we can add new methods without breaking backward compatibility. Also, clients can use all the methods of the type, not just the one defined in interface
There are exceptions in the standard library, for example error
interface and io.LimitReader
function that returns io.Reader
instead of io.LimitedReader
. Although, it seems, that returning io.Reader
instead of a concrete io.LimitReader
was a mistake by Go designers
Obviously, if a function needs to be able to return multiple implementations, it must return an interface
References
- 100 Go Mistakes and How to Avoid Them. Teiva Harsanyi
- SOLID Go Design | Dave Cheney
- Go Proverbs
- GopherCon 2023: Dylan Bourque - Clean Up Your GOOOP: How to Break OOP Muscle Memory - YouTube
- GopherCon 2019: Jonathan Amsterdam - Detecting Incompatible API Changes - YouTube
- Interface pollution in Go · rakyll.org