Go proverbs: "Accept interfaces, return structs." and "The bigger the interface, the weaker the abstraction." Design small interfaces at consumer side—io.Reader, io.Writer are canonical examples.
Consumer-driven interfaces
Define interfaces where they are used, not where types are implemented—keeps packages decoupled and tests easy with fakes.
Testing with fakes
type Storage interface {
Get(key string) (string, error)
}
Implement fake storage in tests without touching production DB code—similar to mocking in Java but via simple structs.
Important interview questions and answers
- Q: Accept interfaces, return structs?
A: APIs accept minimal interfaces for flexibility; return concrete types so callers know what they get. - Q: io.Reader size?
A: One method—easy to implement, compose, and mock.
Self-check
- Where should you define a small interface?
- Why avoid large interfaces?
Tip: "Accept interfaces, return structs"—return concrete types from constructors, accept minimal interfaces in function params.
Interview prep
- Accept interfaces return structs?
Flexible inputs, concrete outputs—callers know what they receive.
- Small interfaces?
io.Reader has one method—easy to implement, compose, and mock.