Five Reasons Why You Should Keep Your Package Dependencies Cycle Free

If you are so unlucky to work with me in a project, you will suffer from the rule that all package dependencies must be cycle free. I will not only require this, but I will also create a unit test ensuring it using Degraph. Here are the reasons why I think a cycle free package structure is beneficial for a project.

  1. Helpful abstractions: If you implement stuff without thinking to much about dependencies you end up with cyclic dependencies almost for sure. In order to break those cycles you often have to introduce new abstractions in the form of interfaces. These interfaces often turnout to create a cleaner abstraction of what is going on in the application than the direct dependency that was there before.

    For example consider two packages Something and Other that depend on each other. As it is described, there is no way to tell why they depend on each other. But in order to break one of the dependencies you might decide to introduce an interface. The name of that interface might include valuable additional information about the relationship of the two. Imagine the interface ends up being named SomethingDeletionListener and located in Somehting and implemented in Other. This already tells you something about the relationship of the two packages, doesn’t it?

  2. Clean Orthogonal Package Structure: Whenever you organize something in a tree like structure you probably want an orthogonal structure in that tree. This means on all subbranches of a branch are elements of single categorization. A good example is Customer, Order, Wishlist a different, also good example is UserInterface, Persistence, Domain. These kinds of structures gives a clear indication where a class belongs. If you mix the two approaches you end up with something like Customer, Order, Persistence. In such a structure it is not at all clear where classes for the persistence of customers belong. The result is a mess, which typically results in cycles in the dependencies, since a question like should Customer depend on Persistence or the other way around doesn’t even make sense.
  3. Enables reuse: Ever tried to reuse a package or even just a single class from a project that doesn’t care about dependencies? I tried. In 9 out of 10 cases I had two choices: Either take the complete project (not really an option), or do some heavy refactoring of the class before it even compiles without all the other stuff in the project. On the other hand in projects where package dependencies form a nice directed acyclic graph, it is perfectly clear what has to go with the class. Also the stuff people are interested in reusing is typically close to the leaves of the graph and can be extracted on it’s own or with very few dependencies.
  4. Enables partial rewrites: Sometimes an idea once considered great turns out to be a really bad one. Sometimes it is so bad, you want to redo it. Acyclic dependencies limit the amount of code affected by the change. With cyclic dependencies often the complete application is at least in danger of being affected.
  5. Independent deployment: On the other hand, sometimes ideas actually turn out to be great. Maybe so great that they get used so heavily, that you need to scale it up and deploy it on three additional servers on its own, to handle the heavy load. Good luck in splitting your application in two or more parts that can be deployed separately when you have tangles between the packages. With a cycle free structure, the places where you can cut should be rather obvious.

Why you should avoid JSF

For a long time JSF for me was just another webframework I didn’t cared too much about. This changed. After being forced to use it for a couple of months now, I consider it a major project risk in almost all cases. Here I present the reasons for this verdict.

Bad entanglement of UI and processing Logic The official tutorial claims the following about the benefits of JSF:

One of the greatest advantages of Java Server Faces technology is that it offers a clean separation between behavior and presentation for web applications.

The opposite is the case. Facelets, the preferred presentation technology of JSF looks at first sight like an ordinary templating technology like the good old JSP or Thyme Leaf. But if you look closer the horror becomes obvious. In the same place where you structure your HTML, you also place the logic what parts of the UI should get updated on an action. A clear violation of the separation of concerns principle in my book.

Even better is the immediate attribute which changes the server side life cycle! And if this isn’t enough it does it in different ways depending on what tag you use it on. You can’t make stuff like this up.

It tries to abstract what you can not abstract. Except some weird edge cases clients and server of web application are located on rather different computers, separated by some kind of network. From this follows a simple fact: communication between client and server is slow and unreliable. JSF tries to abstract away the separation of client and server. It processes everything on the backend wildly communicating between client and server in a hard to control way. The result are all kind of failure scenarios just popping into existence because you use JSF. For me the most annoying one is this one: If you open a JSF page, let’s say a simple search page, wait an hour, then hit the submit button you will get an exception because the server side state expired. WAT? Why is there server state of any relevance for a trivial search page? (Yes I know you can change that behavior with the latest versions of JSF, but it is still the way JSF is designed to work) I though everybody learned since EJBs: If you want to abstract over the fact, if two parts of an application run on the same machine or not, you have to assume they don’t. Everything else is just hiding problems until they grow so large that they can eat your project for breakfast.

Making stuff complex and complicated that was easy to start with. The architecture of the World Wide Web is a simple one. Simple meaning: It consists of a small set of concepts with limited interaction. This is what made it so widely successful. It also makes it not obvious for beginners how to use it to implement certain features. I’m sure most of us remember the first time they tried to implement something like a shopping cart without having session state. But the solutions for almost all these problems are well known and understood by know. And all you need is a little reading and what you gain is a strong conceptual understanding how to solve this kind of issue. And again, the basics are extremely simple: You send a request to an URL, with some headers and content using a HTTP verb. And you reply with some resource containing links and some headers. And you don’t have state in the server session. Making load balancing and fail over rather simple. Making bookmarkable URLs trivial. Making your site searchable for zero costs. Making your site cachable. Allowing the user to use their back buttons, history and tabs as they wish. Making it trivial to have nice URLs

Compare that to the live cycle model of JSF: The page from which a user submitted a request will get synchronized with a model on the server side, then submitted values validated, converted, events generated and processed. As mentioned above the order in which things happen, and if they happen at all are controlled by XML Tags hidden away in a document camouflaged as markup. Apart from hardly anybody properly understanding all this (BalusC seems to be the only one available in the interwebs) it has the following effect on your application: The URLs become ugly. You’ll see the URL of the resource you came from instead of the one you are looking at, thus making bookmarking URLs as useful as a doorknob on your knee. Same for caching, fail over, load balancing and so on.

Sure you can fix it with some convention here, and an additional library there. Which of course makes perfect sense when you are in the business of breaking stuff so people have to pay you for fixing it. I personally prefer helping to solve real problems.

Hindering testability: I can’t speak for most frameworks but I can compare Spring MVC with JSF. Let me tell you this: If anybody is telling you JSF is nicely testable he probably doesn’t know automatic testing. With JSF you can test your backend beans using unit tests. You can test the whole UI, by deploying the application to a server and hitting it with Selenium. That’s basically it.

Just in case you are wondering what else one should be able to test: Load a static version of a page in a browser and testing it with selenium, in order test your Client side UI behavior. Test your generated markup without starting a full blown application server. Test the mapping of attributes/parameter to bean methods. Test your generated markup without bootstrapping a complete application. All this is perfectly possible with Spring MVC and probably with many other sane server side frameworks, but not with JSF …

Again: I’m aware there are fixes for many issues, but the simplest fix is> Don’t use JSF.

Quo Vadis JUnit

For me JUnit is the most important library of the Java universe. But I think a new version of it is overdue. With it’s approach of having a method definition as a test definition JUnit is mighty inflexible and needs various hacks … sorry features, to do what you really should be able to do with basic (Java 8) language features.

If you aren’t sure, what I’m talking about, check out this article about ScalaTest. Something like this should be the standard for JUnit.

Of course you can implement your own TestRunner to get something like this going. But there are already many important TestRunners (SpringJUnit4ClassRunner anyone?) and they have the huge drawback that you can have only one of them.

Another alternative would be to just say good-bye to JUnit and use a different Testframework. But all these other Testframeworks don’t have the support from third-party tools that JUnit has, so I’d really prefer JUnit to evolve, instead of it being replaced by something else.

I was thinking about these issues for quite some time and actually brought them up on the JUnit mailing list, with lots of interesting feedback, but nothing happened. So when I met Marc, one of the JUnit committers at the XP-Days we started to discuss the situation, joined by Stefan, another JUnit committer and various XP-Days participants.

And as so often nothing is as easy as it seems. JUnit is a very successful library, but it also doesn’t offer all the features people want or need. This has the effect that people use JUnit in all kinds of weird ways, which makes it really hard to evolve. E.g. Marc and Stefan told a story about the latest version of JUnit where they learned that a certain IDE uses reflection on private fields of JUnit, resulting in a “Bug” when the name of that field was changed.

Therefore it seems, before one can make a change as big as a different default TestRunner, one has to revamp JUnit.

I envision something like the following:

  • gather the various features that others bolted onto JUnit, that probably should be part of JUnit itself.
  • provide a clean, supported API for those
  • apply gentle pressure and time for third parties to switch to the new APIs
  • behind that API provide a new more flexible way to create tests
  • profit

And since JUnit is an open source project and all developers seem to work only in their private time on it, we started right there at the XP-Days gathering stuff that needs consideration. I put the results in a wiki page in the JUnit github repository. Get over there and see if you can add something.

Softwaredevelopment, Learning, Qualitymanagement and all things "schauderhaft"