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 :
sonar-design-erosion-1

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.

  • Hi, I’ve a post in Spanish trying to explain the same Sonar2 feature. It’s more schematic than yours but it could be a good entry point. Sorry if you think that i’m spamming (fell free to remove the comment :)

    http://emilio-escobar.blogspot.com/2010/03/como-romper-dependencias-ciclicas-entre.html

  • Everyone can experiment this feature on several open source projects (Tomcat, Maven, JBoss, …) on Sonar live instance : http://nemo.sonarsource.org/

  • Sonar: “Package list has 2 incoming dependencies from package iterator that must be cut.”
    Me: How do I cut them? They are necessary!

  • You should consider this signal sent by Sonar like an alarm : you’ve a cycle in your design ! Either, this is a due to a narrow scope error or you do have a more structural quality issue in your design.

  • Ok, for everyone who have problem to cut the cross-package cycle dependedcies: If you think these dependencies are 100% necessary, then it means you put a file in a wrong package, and you should move it.

  • I believe there’s two different cases in which package cycles can be dealt with.

    First, there could be a classic 3-tier design separating UI-Service-Data layers in different packages each. In that case, I completely agree that it’s almost always a bad idea to have a cyclic references among them.

    However, think about a two different interfaces which naturally considered as a part of a tightly integrated whole (possibly with a composite relationship), but kept in separate pakages for maintenance purpose.

    Say, if you design an IDE like UI and there’s a concept of an window consist of multiple views.

    In that case, myapp.ui.Window interface can have a reference to a collection of myapp.ui.view.View instances, like Window.getViews() and an AbstractView class in the same package as the latter can very well has getApplication() method to reference the parent application instance.

    Of course, in some cases you can just put Window and View interfaces in the same package to solve such a cylcle. However, when there are many view related classes (which are not concrete implementations) in ui.view package, one often finds it not very viable to take such an approach.

    In summary, I don’t think every package cycle is a problem. Especially, in a case where interfaces or abstract classes in difference packages reference each other I believe there could be many justifiable usage for a design involves a cyclic package reference.

  • @Xavier, I tend to agree with you “I don’t think every package cycle is a problem” and indeed Sonar should allow :

    * At short term: to flag some cycles/dependencies as ‘accepted/expected’
    * At long term: to allow to define some architecture layers and to detect cycles only between those layers

    Thanks for your feedback

Leave a reply


4 × = twenty