Btw. Interfaces can also be used to resolve circular dependencies: Just define compatible interfaces in both packages et voilà, no circular dependencies anymore.
I am not sure if I agree with
> Defining an interface upfront is usually a code smell for overengineering.
So far I had less problems with overusing interfaces than with not using them enough. So when you write tests for a package, you define the general interface to the package in terms of types and methods. The remaining challenge is to break that general definition into smaller pieces as one big interface for a package is almost certainly a bad idea.
However, in general I follow the authors verdict to not just build 'Java-style' interfaces, as that completely misses the point of interfaces in Go.
If you have circular dependencies you're doing something wrong. By disagreeing with that and accepting circular dependencies as a normal state of the Go code, you put yourself in the position of doing another wrongness: defining a lot of interfaces.
There is some stuff I really love about Go, but the seemingly pervasive "you're doing that wrong" culture typified by your comment is a really bad look for a language community. It is much better to show people why things are better than to make proclamations. Neither of the things you proclaim to be "wrong" are wrong a priori; show us why your way is better.
Having recently moved into go at work and interfacing with its community, I 100% agree with this. The absolute dogma drives me crazy and makes me not want to deal with the go community at all.
Well, it might be that I was doing something wrong, but in the end I didn't have circular dependencies anymore, so I was doing right again? (just kidding) ;-)
So in fact, I don't like to have circular dependencies in Go either and try to avoid them, so I agree with you on that. But at the same time I like very small and simple packages and sometimes you have to choose:
1. do you build a larger package with everything inside
2. do you build multiple smaller packages with dependencies on each other
As I said, in general, I favor the smaller packages and that can lead to circular dependencies, if you are not using interfaces properly.
But I still think that you have multiple packages and each one is calling all the other ones, then it doesn't make much sense to have multiple packages at all.
I prefer smaller packages too, but currently I'm trying to avoid overmodularizing, specially when a package is too connected to some others and is not going to be used elsewhere.
I am not sure if I agree with
> Defining an interface upfront is usually a code smell for overengineering.
So far I had less problems with overusing interfaces than with not using them enough. So when you write tests for a package, you define the general interface to the package in terms of types and methods. The remaining challenge is to break that general definition into smaller pieces as one big interface for a package is almost certainly a bad idea.
However, in general I follow the authors verdict to not just build 'Java-style' interfaces, as that completely misses the point of interfaces in Go.