简体   繁体   中英

How to solve this Go cyclical dependency

I've been learning Go for a class course and I am very excited with the language, it really is very useful for web services.

So, I've been writing this CRUD restful API for a final project and I keep running in the damn circular dependency problem. I've already researched and read on the ways of solving it and will post here just for the sake of it, but first the problem I am having:

routes need to know about the handler functions in the handlers package, which in turn need to know about the user structure inside the model package, which in order to send a registration e-mail with a link need to know about the routes path

Classical A -> B -> C -> A

Now, I am trying to write this API using MVC and three layer architecture, this I would love for my routes to be in a controller package, my handlers to be on a business logic package and my user on a model package. This is also needed because I have over 43 model classes, I need them tidy up and tucked away on their package.

Ok, the solutions I found out

1 - Throw everybody on the same package : That's what I've been doing so far but is a very horrible solution for obvious reasons.

2- Pass whatever user needs as argument when it's functions are called : That would be a good solution, but won't work because the function that is being called from user is from an interface implementation because it has to be a generic call and before anyone goes around saying that my problem is because I am forcing generics in go, well too bad, I need that generic, I will not write over 160 crud functions. The whole point of functions is to avoid code repetition.

3- Create another package, with another interface, and have it having a instance of handlers and user and have it pass arguments from one to the other : Despite the reason mentioned above, the need of generic, this sounds like an unnecessarily complicated solution, I refuse to believe that this is better design than circular dependencies.

Bottom line question: How to solve this dependency when C needs to know information from A and generics must be respected

I can post some code here if you need to but I don't see the relevance of specific code when this is more of a high level question.

EDIT : Solved my dependency problem. Thank you all for the comments and answer as it led me to the answer. I don't think I've implemented any of the solutions suggested but it did taught me a lot about how to solve the problem, and they would all be very acceptable and doable solution if it wasn't for my own constrains where I don't want to pass anything to User. To anyone trying to solve their own dependency problem, what I was able to gather is, instead of making in my case, C ask something from A, give to C whatever it needs, before it has to ask, meaning pass the information to him.

Alas, that was not my solution, what I did was remove the information from A and give the information to Z, now both A and C are asking the path information to Z, which is just a Map, sitting there being all map like and holding information. Thank you all

You've got some options, and you've found some of them. The main ways of handling this are:

  • Refactor your design to turn the cycle into a tree. This doesn't really apply to your situation due to your requirements.
  • Refactor your design to use some kind of dependency injection (this is your 2nd option in your question). This is perfectly viable, and probably the cleanest and easiest.
  • Refactor your design to take a locally declared interface. This is a more Go-idiomatic version of your option 3. Because interfaces in Go are duck-typed, you get to define it where it's consumed, rather than where it's implemented. So your user package can define a one-method interface for "a thing that gives me a URL I need" and it never needs to reference the package that implements the interface.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM