Layered Design in Go
great blog post! also this website has a lot of incredible posts, if you like learning about functional programming, you should check out
https://jerf.org/iri/blogbooks/functional-programming-lesson...
One bonus technique related to the “move to a third package” advice: generating many of your model structures (SQL, Protobuf, graphql, etc) allows you to set up obvious directionality between generated layers and to provide all generated code as “base packages” to your application code, which then composes everything together.
Prior to this technique we often had “models importing models circularly” as an issue but that’s entirely disappeared due to the introduction of the structural additional layer.
Looks like I am reading a book about Yourdon structured method.
> Packages may not circularly reference each other.
Actually possible with go:linkname.
Kind of reminds me of the concept of spheres in randomizers
A funny quirk about golang is you cannot have circular dependencies at the package level, but you can have circular dependencies in go.mod
The tl;dr is don't do that either.
Cool description of how jerf thinks about packages and how he deals with circular dependencies!
In my opinion, not allowing circular dependencies is a great design choice for building large programs. It forces you to separate your concerns properly.
If you get a circular dependency something is wrong with your design and the article does a good job on how to fix them.
I sometimes use function pointers which other packages override to fix circular dependencies which I don't think was mentioned in the article.
My only wish is that the go compiler gave more helpful output when you make a circular dependency. Currently it gives a list of all the packages involved in the loop which can be quite long, though generally it is the last thing you changed which caused the problem.