Rather than defining all these one-method interfaces, why not specify a function type?
Instead of
type Saver interface {
Save(data []byte) error
}
You could have
type saves func([]byte) error
Seems less bulky than an interface, more concise to mock too.
It's more effort when you need to "promote" the port / input type to a full interface, but I think that's a reasonable tradeoff to avoid callers of your function constantly creating structs just to hang methods off
With Go had something similar to Java's `@FunctionalInterface` annotation, where a functions signature (parameters and return type) is implicitly matched against the single abstract method of a functional interface and where existing matching methods of any object can also be used as implementations of functional interfaces.
You can do this in Go by making a type declaration defining a function and then adding a method with the same signature on that type, which calls the function. The Go standard library does exactly this with the `HandlerFunc` type [1].
// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// [Handler] that calls f.
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
Instead of
You could have Seems less bulky than an interface, more concise to mock too.It's more effort when you need to "promote" the port / input type to a full interface, but I think that's a reasonable tradeoff to avoid callers of your function constantly creating structs just to hang methods off