Friday, January 30, 2009

Tangled and circular dependencies

Back to the cyclical dependencies problem I wrote about one year ago, the other day I finally tackled it (15 years spent playing rugby must have taught me something), as it was left hanging in the air for too long. We started out like this:

Basically project B uses the domain model and persistence services from project A, which in turns uses transport services and a the domain model from project B (no, it is not the same as above, because the model B is just based on model A but it is managed from a different perspective). Let's not forget to say that presentation, model and services are all tangled.

A disclaimer: this is not what I'd call a refactor, just a different way of organizing projects thanks to NetBeans features (no Maven complexities, thank you).

I first extracted the core domain classes of project A used in project B and moved them to a new project, let's call it A Core, then had both project A and B depending on this one. Sounds easy, but it wasn't... it was quite long and tiring, and it required a little tweaking each now and then, just like the subsequent passages. That lead me here:

Now that could look good, but even if it is better it was not enough because of some legacy installations in which Project A must be compiled using JDK 1.4 and run on a Tomcat 4, but project B has a JDK 1.5 source level (Tiger, or whatever it is called now) and runs on a Tomcat 6. This forced me to extract from Project B all classes on which Project A depended to move them on a new project, let's call it B core. Nip and tuck, here and there, to land that prince with the perfect hair, and here we are:

Now all cyclical dependencies are gone. Packages with the very same name exist in different projects, leading to a namespace which "doesn't talk" to the developer; on the other hand this can bring a lot of confusion, even if the compiler understands everything perfectly. That's where fun begins... I just began scraping the surface, now we have to dig in deep. The first step will be choosing the right names for packages, so to convey the rationale behind their repositioning. The next one will be moving related classes left untouched by the dependencies game but logically belonging to one of the "core" projects. Other steps are still up in the air...

Moral: always clean up your mess. BTW, it does not matter if you just inherited it. Now it is yours, and it is you the one who has to deal with it. Leave spaghetti to gravy and keep them out of your code. There must be a reason if they say "clean code that works" and not just "code that works"...

No comments: