Fight Back Design Erosion by Breaking Cycles with Sonar
With version 2.0, Sonar now embarks the seventh and last axis of source code quality : Design & Architecture. The objective of this post is to start discussing what it can be used for and why it is so important.
To know if the design of your software is in a good shape, having a sense of observation and a good memory can most of the time do the trick. No real need to use a tool (whether it is UML diagrams, Sonar...) or to look at source code. If month after month, your software is able to evolve as quickly as the business requires and can handle the changes at a constant cost throughout time, then you can confidently conclude that the design of your application is in a good shape (and believe me, it is fairly unusual in the software development market !). If not, you should focus some attention on design as it is not going to get better over time and will become costly in the medium to long term.
To handle fearlessly upcoming changes, it is key that the software design has great modularity. That is to say, you can replace part of the system by a new piece of code with little pain. Reaching true modularity can only be achieved in a programming environment that has two main capabilities (two dimensions) : ability to assemble pieces of software and ability to recursively split a piece of software. However, these capabilities are necessary but not sufficient.
For instance in Java, an application can be split into jar libraries, a jar library can be split into packages, packages into files, files into classes, classes into methods. And of course you can assemble jar, assemble packages, assemble classes and assemble methods. But does that mean that any Java application is modular ? Unfortunately not, Java applications can be as monolithic as old but robust COBOL programs are.
Design is rarely bad from the beginning, but some kind of erosion can gradually rigidify any good design. First level indicators should be checked on a regular basis to prevent such erosion. The first of them is the existence of cycles between packages. It basically tells you : "Hey guys be careful, your overall architecture seems to stiffen !". Indeed when two, three or four packages are involved in a cycle, it means that those packages can't be split. If all your packages are involved in cycles, it means that your whole application is not a puzzle anymore but a kind of big stone instead. Nobody intends to create cycles but everybody creates one, one day or an other. Cycles tend to creep in our design like weeds in the garden.
Once you know there are cycles, you will certainly want to hunt them down, understand what happens and cut them. To do so, simply initiate a dialog with Sonar :
You : “Argh… more than 37 package cycles in my project.”
Sonar : “And the tangle index is high : overall architecture is pretty bad.”
You : “What should I do ?”
Sonar : “You need to cut 12 dependencies between packages.
”You : “Is that a big job ?
”Sonar : “Yes, because it involves 135 dependencies between files.”
You : “Where do I start from ?”
Sonar : “Click !”
Sonar : “Here are the dependencies to cut.”
Sonar : “Package list has 2 incoming dependencies from package iterator that must be cut.”
You : “What are the files involved ?”
Sonar : “Click !”
Sonar : “Here are the two dependencies between files to cut”
You : “Can I view the source code ?”
Sonar : “Click !”
You : “Time for refactoring !”
To give you the complete picture, I have to say that if you wish to go further on Design & Architecture you might want to use tools such as Structure101, SonarJ and Xdepends that are really pretty good. Sonar 2.0 features have been initially inspired by them.