I'm playing with converting an old project that needs a rewrite into Go. Most of my initial attempts have been looking successful but I've run into a problem with import cycles.
My project structure looks like this:
model
orgs
org.go
events
event.go
shows
show.go
entries
exhibitor.go
entry.go
fees
premiums
etc.
There are typically 3-8 go files in each leaf directory. There are currently 9 child directories under model. That will about double.
Here's the problem part. Each .go file typically contains a struct like this:
import (
"model/shows"
)
type Event struct {
ownerOrg *orgs.Org // reference back to the sponsoring organization
showList []*Show // list of each show in the event
}
.
import (
"model/entries"
"model/events"
)
type Show struct {
ownerEvent *events.Event // reference back to the owner event
exhibitorList []*entries.Exhibitor // list of exhibitors entered in the show
}
.
import (
"model/shows"
)
type Exhibitor struct {
ownerShow *shows.Show // reference back to the owner show
entryList []*entries.Entry // list of entries for this exhibitor
}
Having the back reference and the forward lists is giving me cycle issues.
Note: there are often more than one "owner" type references in each struct and almost always more then one "list" slices in each struct. This just compounds the problem.
Here's what I've tried and my best current solution (which is okay but not very Go-ish).
Factoring to interfaces. This is the "typically" import cycle solution I see. It doesn't seem appropriate (or even possible?) when the problem is structural rather than behavioral.
Change "owners" to be interfaces. I'm pretty sure this I could get this to work but seems to lead to a worse structure. It would have lots of type conversion and factoring out behaviors into weird .go files. Code no longer "near" where it's expected or used. This would leave me with what I'd consider a difficult structure for other coders to understand and use with no gain except to make the compiler happy.
Big ball-o-mud. Just put all the 50+ .go files into one package. This solves the cycle problem but creates readability and understanding problems.
Unorthodox prefixes. (My current thinking.) I can combine the big ball-o-mud with directory prefixes so I end up with this structure:
.
model
orgs_org.go
events_event.go
shows_show.go
entries_exhibitor.go
entries_entry.go
etc.
Outside of having not seen it, is it really terrible or just "odd?" It does seemingly solve my problem and it keeps functionality where it's expected and where it's used.
Is there a better "Go way" that anyone knows for this (typical to me) business object structure?