What I look for in frameworks

In every project the discussion comes up over and over again: should we use framework X? or Y? or no framework at all? Even when you limit yourself to the frameworks for web development in the Java space the choices are so plentiful, nobody can know them all. So I need a quick way do identify which frameworks sound promising to me and which I keep for weekend projects.

  1. Stay away from the new kid on the block. While it might be fun to play with the coolest newest thing, I work on projects that have a life cycle of 10-30 years. I wouldn’t want to support an application using some library that was cool between March and July in 1996. Therefore I try not to put that kind of burden on others.
  2. Do one thing and do it well. A bad example for this is Hibernate/JPA. It does (or tries to) provide all of the following

    • mapping between a relational and an object-oriented model
    • caching
    • change detection
    • caching
    • query dsl

    It is kind of ok for a framework or library to provide multiple services, if you can decide on each service separately if you want to use it or not. But if it controls to many aspects of your project, the chance that it doesn’t do anything well gets huge. And you won’t be able to exchange it easily, because now you have to replace half a dozen libraries at once.

  3. Method calls are cool. Annotations are ok. Byte code manipulation is scary. Code generation a reason to run for the hills. In the list only method calls can be abstracted over properly. All the other stuff tends to get in your way. Annotations are kind of harmless, but it is easy to get in situations where you have more annotations than actual code. Byte code manipulation starts to put some serious constraints on what you can do in your code. And code generation additional slows down your build process.
  4. Keep the fingers of my domain model. The domain model is really the important part of an application. I can change the persistence or the ui of an application, but if I have to rework the domain model, everything changes and I’m essential rewriting the application. Also I need all the flexibility the programming language of choice offers to design the domain model. I don’t want to get restricted by some stupid framework that requires default constructors or getters and setters for all fields.
  5. Can we handle it? There are many things that sound really awesome, but they require a so different style of coding, that many developers will have a hard time tackling it. And just because I think I can handle it, doesn’t necessarily mean I actually can. So better stay simple and old-fashioned.

The Latest Version of Degraph is Available for Download at Maven Central

Degraph is my personal open source project for visualizing and testing package dependencies in JVM byte code. I released the latest version 0.1.1, so go grab it while it is hot.

What’s new

This release in mainly a bug fixing release. So the important changes are two bug fixes. Degraph 0.1.0 missed a few dependencies to static methods, and through class valued annotations. So you absolutely should upgrade. I hope you don’t use many static methods, so the first bug won’t bite you as bad. The second one is actually quite annoying with certain frameworks. Spring for example uses lot’s of annotations, including those that contain references to classes.

Fortunately upgrading your tests will be easy, because degraph-check is now available through Maven Central, which makes using it really a no-brainer.

Although this release is just a minor one, a tiny new feature slipped in almost by accident. And when I tried it at work it turned out to be extremely helpful: You can now instruct Degraph to create a graphml file for failed tests. Just provide a path using the printTo method. An example looks like this:

  1.   test("Check identifies cycles in junit") {
  2.     classpath.printTo("junitDependencyFailure.graphml").including("**.junit.**") should  not be (violationFree)
  3.   }

This allows for a relative quick workflow:

  • Write your test
  • Run the test
  • Open the resulting graphml file in yed
  • Modify code or test
  • Run the test
  • Reopen in yed
  • Repeat the previous three steps until done

I found this tremendously helpful when fixing the problems that the bugfixes mentioned before surfaced.

Give it a try and let me know about your experiences in the comments below, or in the issue tracker over at github.

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.

Softwaredevelopment, Learning, Qualitymanagement and all things "schauderhaft"