SONAR Rules and Technical Debt

This is short narrative compared to my first one on Evolutionary Architecture, but I think it can have a big impact on how practitioner teams work these days. Many teams use SONAR (or related tools) to measure Technical Debt. These tools analyze your code base and estimate: your current debt is 2345,94 USD. They also support you with a pre-configured set of rules to determine what’s important to fix and what is not. SONAR, for example, categorizes debt items as info, minor, major, critical and blocker. A missing documentation of a method is “major”, also a magic number or a duplicated String value. If you iterate over a Map in a very inefficient way, it’s surprisingly “critical”. But to be fair, possible NullPointerExceptions are also “critical”. These issues are usually easy to fix.
To my surprise, classes with 1000 LoC and/or 15 dependencies on class level are OK, and even worse: if you have a class with 3000 LoC and 30 class level dependencies, you only have a major problem.

What do teams do if they have 250 SONAR violations? Right, they try to get rid of most of them as quickly as possible, by usually choosing the easy ones first. In the end, you have only 3 major issues left, unfortunately 2 really complex god classes with many dependencies and one 500 LoC method with a very high cyclomatic complexity. All is good! Only 3 major problems, we can lay back and relax! Our code is awesome and we don’t have much Technical Debt.

What are you saying, Sven? We only fixed the unimportant stuff? We should better have fixed the 3 remaining issues instead, because they are really slowing us down. They cause a lot of bugs and it’s really hard to make changes in these classes and methods? No, no, we disagree, because a) the SONAR guys are the real experts in this, they do the whole day nothing else than debt analysis and when they say something is major or critical they are probably right and you are not; b) it takes a lot of time to fix these 3 issues, if even possible. This code is really complex and it is really risky to break down! The way we did it makes even the management happy, because we spent only a couple of hours to basically reduce our Technical Debt to 400 USD and SONAR looks really good right now!

Maybe most of my colleagues are right with that. But I would be really happy if we could analyze the current state-of-the-practice during the workshop and, if necessary, come up with a better proposal on how tool vendors should categorize Technical Debt. Every team is of course free to configure their own importance of rules, but a solid and often cited publication will help to drive discussions besides “but SONAR says so”.

Evolutionary Architecture and Technical Debt

Evolutionary Architecture (EA) is an approach discovered by Neal Ford and Rebecca Parsons to help teams that need to deliver software early and often. This basically includes almost all teams developing enterprise software. Although a great idea implementing managing Technical Debt as a core principle, it is not picked up widely by the industry, which I think is worth exploring.

I offer two reasons – besides the early market entry – why teams accumulate structural / architectural debt, which to my surprise are rarely described:
(1) Most teams are using Scrum or nowadays also Lean Enterprise / Lean startup ideas to create software based products. In all of these approaches you have to deliver early and often, you don’t have much time for up-front architectural work, business stakeholders expect to see the first functionalities after 2-3 weeks, and more and more the following weeks. One experience, which drives this approach, is that many beautifully engineered software products have been built, but nobody wanted to use them – a waste of money. What’s the point of having a perfectly architected system nobody wants? New approaches focus first on finding out what users want with as little investment as possible (e.g. a MVP – minimal viable product or A/B testing). This deliberately causes structural / architectural debt (also other kinds of debt, but those are the expensive ones to really care about).
(2) Delivering visible functionality early and continuously has an additional benefit: it builds trust between the development team and the business stakeholders. Since software is invisible, it is really hard to explain why you create all these diagrams, documents, have all these meetings and discussion. The first times you are a business stakeholder, you understand that upfront investment in architecture doesn’t pay off immediately, but saves you a lot of effort and costs in the medium and long run. But after a few projects you realize that architecture is also a hypothesis about the future: things might end up differently. For example you give the development team enough time, but if the future is different than anticipated, developers might not be to build new functionalities due to the time necessary to revert wrong decisions from the beginning. But if you get features early and regularly, in my experience you are much more open and relaxed to spend money for architectural concerns later without fighting for every penny. The developers delivered what you want first and they showed that they understand that meeting business needs early on is usually more important than meeting technological needs. Bad architecture, however, is really costly (e.g. slow development, more and more bugs, stability problems) and quickly becomes a concern for the whole organization, which needs to be addressed immediately.

The EA practice helps to incrementally build and improve the architecture while uncovering and addressing architectural issues during software development without investing in significant up-front design (see also Eclipse practice page). This means that you only implement what you need right now to deliver your product successfully, knowing that things will change over time and you address the problems when they arise. Of course it’s not that simple because you need to discover, document, track and evaluate possible problems constantly.
One of its 5 core principles is described as “The last responsible moment – delay decisions as long as you can, but no longer” and this is all about managing Technical Debt (the other 4 are: architect and develop for evolvability, Postel’s law, architect for testability, and Conway’s law).

However, finding the last responsible moment is a difficult task. Mostly this moment passes by and you recognize it when it’s too late and then it is really too late: fixing the problem then becomes very expensive and risky. Ford and Parsons recommend to address architectural risks by constantly evaluating the current state of your system against “fitness functions” (a.k.a. quality attributes, non-functional requirements). How to recognize the last responsible moment is so far poorly described.

Except for a few articles and presentations, there is no documentation, guidance, templates or case studies to help you get started with EA. During the workshop I would like to figure out whether EA is a valid practice to tackle the problem of structural/architectural debt introduced by the pressure of faster market entry, deliver early and often and building trust. And if so, what do we need to describe and provide for practitioners and the community to get started, experiment, apply and improve this practice.