One basic but important customer expectation is that their software product should be of very good quality. While this expectation makes sense, what exactly does “good quality” mean? Here are characteristics of good quality software:
Software should be able to perform all of its functionalities as expected (i.e., defined in acceptance criteria).
Software should meet all non-functional “ilities” (e.g., scalability, reliability, etc.).
Code quality should be great with minimal technical debt.
When it comes to code quality, people in the software industry have different perceptions and interpretations of it. Most of the time, these interpretations are abstract and do not necessarily define code quality in measurable terms. So before we move any further, let’s define what code quality exactly means.
“Code quality is an indicator of how quickly a developer can add business value to a software system.”
Now that we know what “code quality” means, the next relevant questions are, “How do we measure it, and how do we get the sense of it in real time?” Code quality is measured (or rather, the lack of it is measured) in form of the “seven sins of code quality.”
Bugs and Potential Bugs. Bugs and potential bugs make up the most urgent sin, as it shows what’s wrong in your code currently and what can go wrong tomorrow (e.g., NullPointerException).
Coding Standards. Consistent and agreed upon coding standard and style is much easier to follow rather than multiple coding styles in the same project. A more serious example of this type of sin is the failure to follow naming conventions.
Duplications. Although duplications don’t seem like a big deal, they are not efficient in the long run. Similar to Murphy’s Law, the more places into which a chunk of logic has been duplicated, the more likely it will need to be changed – and probably with a high level of urgency or criticality.
Lack of Unit Tests. Unit tests help keep bugs and regressions from slipping into production code. And when you make a change to existing code, they help you know that you didn’t break it.
Bad Distribution of Complexity. It’s okay for a program to have some complex files and methods, but if you have too many of them, the next developer who has to work on the application will have a hard time understanding what’s going on in the code. And if he/she has a hard time understanding it, he/she will have an even harder time successfully modifying it.
Not Enough or Too Many Comments. This is a measure of maintainability. Ideally, the code should be clear enough that one shouldn’t require to look at comments. However, comments become more important when the libraries and APIs are exposed to clients. Instead of looking into the code, one should be able to find the relevant information to use the APIs using coding documentation.
Spaghetti Design. Spaghetti design is having a high level of complexity at the project architecture level rather than in a single method or file. New developers on the team will have a hard time understanding how the project is organized and where new code should be put.
So now as we know the different metrics for measuring code quality, let’s see how to measure them.
Code quality needs to be measured in the form of density; abstract numbers are useless. For instance, 400 potential bugs as a number in itself doesn’t tell the severity of the issue. However, when one talks about it in form of potential bug density, you get a better picture. Also, it’s important to observe the trend of code quality throughout a specific period of time.
There are tools that measure code quality and provide a real-time snapshot of code quality through reports. Although these tools are great resources, reports are rather reactive and not actionable. It makes much more sense for a developer to discover the error as soon as she/he makes one. Without fixing the error, such a system wouldn’t allow her/him to move further. That sounds much more proactive, doesn’t it?
In next section, let’s see how to apply code quality checks in a proactive way.
Step 1: Use IDEs with the necessary code quality plugins (i.e., for Java FindBugs, Checkstyle, PMD, PMD-CPD) and install them so that you catch the problem as you type the code in IDE. If you want to take this approach a step farther, you can use Puppet and Chef to install a consistent developer environment on each machine so that there is no question about plugins installed or not installed, versions of different application software and tools, etc.
Code quality measurement and continuous improvement is not about reactively generating reports and making plans to improve it. Instead of fixing quality issues when they already raise their heads in reports, you should proactively not let them happen in the first place. Apart from quality plugins used with automated builds, IDE plugins and CI plugins help a lot in achieving the holistic agenda of clean code.