Measuring code quality nowadays is more and more important. With businesses both critical and non-critical depending on software more and more, assessing the quality of a business by the quality of its code, has become a key step in ensuring a full picture of such business's landscape.
There are multiple ways one can adopt for measuring code quality: static analysis tools like SonarQube, external consultants can validate the software, etc.
We will look at a code analysis tool called BetterCodeHub to assess code quality.
What is BetterCodeHub?
BetterCodeHub is a tool developed by Software Improvement Group B.V. that checks your code against 10 software development guidelines that comprise good software development practices.
Each of the guidelines in isolation is pretty simple to understand, but, when combined with the others, and, when evaluated as a whole, it's easy to see why they'd comprise the definition of good software. Let's see the guidelines one by one.
The 10 guidelines in BetterCodeHub ensure that your codebase is well-structured,with a well-defined organization, can adapt to changing requirements, and the code is easy to follow.
While the guidelines might seem very simple, it’s safer to say they are deceptively simple, in the sense that it’s sometimes difficult to adhere to the guidelines strictly, and also, that might not always be possible due to external factors, such as time constraints, legacy code, etc.
However, if you follow them, your code will be easy to maintain and extend, which will enable future developments on the code base to be made much more easily.
1 Write short units of code:
- Small units are easier to understand, reuse, and test.
- When writing new units, don't let them grow above 15 lines of code.
- When a unit grows beyond 15 lines of code, you need to shorten it by splitting it into smaller units of no longer than 15 lines of code.
2 Write simple units of code:
- Keeping the number of branch points (if, for, while, etc.) low makes units easier to modify and test. Try to limit the McCabe complexity, that is the number of branch points plus 1, in a unit to at most 5. You can reduce complexity by extracting sub-branches to separate units of no more than 4 branch points.
3 Write code once:
- When code is copied, bugs need to be fixed in multiple places. This is both inefficient and error-prone.
- Avoid duplication by never copy/pasting blocks of code.
- Reduce duplication by extracting shared code, either to a new unit or to a superclass.
4 Keep unit interfaces small:
-Keeping the number of parameters low makes units easier to understand and reuse.
-Limit the number of parameters per unit to at most 2.
-The number of parameters can be reduced by grouping related parameters into objects.
-Alternatively, try extracting parts of units that require fewer parameters.
5 Separate concerns in modules:
-Keep the codebase loosely coupled, as it makes it easier to minimize the consequences of changes.
-Identify and extract responsibilities of large modules to separate modules and hide implementation details behind interfaces.
-Strive to get modules to have no more than 10 incoming calls.
6 Couple architecture components loosely:
-Having loose coupling between top-level components makes it easier to maintain components in isolation.
-Do this by minimising the amount of interface code; that is, code in modules that are both called from and call modules of other components (throughput), and code in modules that are called from modules of other components (incoming).
-You can hide a component's implementation details through various means, e.g. using the "abstract factory" design pattern.
7 Keep architecture components balanced:
-Balancing the number and relative size of components makes it easier to locate code.
-Organize source code in a way that the number of components is between 2 and 12, and ensure the components are of approximately equal size (keep component size uniformity less than 0.71).
-For actionable results, you need to define architecture components, for example by configuring a zoom level in the tab on the right of the guideline view. A zoom level recognizes as architecture components the folders at a particular nesting depth.
8 Keep codebase small:
-Keeping your codebase small improves maintainability, as it's less work to make structural changes in a smaller codebase.
- Avoid codebase growth by actively reducing system size. -Refactor existing code to achieve the same functionality using less volume, and prefer libraries and frameworks over "homegrown" implementations of standard functionality.
- Strive to keep volume below 20 Person-years.
9 Automate tests:
-Automating tests for your codebase makes development more predictable and less risky.
-Add tests for existing code every time you change it.
-For small systems (less than 1,000 lines of code), you should have at least some test code and one assertion (currently only checked for Java and C# systems).
-For medium systems (less than 10,000 lines of code), the total lines of test code should be at least 50% of the total lines of production code, and the assert density (percentage of lines of test code containing assertions) should be at least 1% (currently only checked for Java and C# systems).
-For large systems (more than 10,000 lines of code), the total lines of test code should be at least 50% of the total lines of production code, and the assert density should be at least 5% (currently only checked for Java and C# systems).
10 Write clean code:
-Clean code is more maintainable.
-Proactively search and remove code smells.
-Remove useless comments, commented code blocks, and dead code. Refactor poorly handled exceptions, magic constants, and poorly named units or variables.
Analyzing our project with BCH
If you have been following my flask series you will recall, that during development, we took special care to keep refactoring the code and keeping it clean and simple, taking design decisions with the aim of simplifying our own architecture and code structure.
Let’s see how we fared against BCH:
So, as we can see, we score 9/10 in the BCH guidelines.
This means, that the efforts we took of continuously doing both structural as well as code style refactors while developing our code really helped in keeping our code clean and maintainable.
The most important takeaway from this, is that this is an activity that needs to be performed relentlessly and continuously, as over time, as the codebase grows, the requests for new features grow, and the complexity inevitably increases, the maintainability of the code will tend to decrease. So, refactor constantly and seek opportunities to do so.
We saw the value of a tool like BCH in helping us writing clean and maintainable code and most importantly, it offers us so much more:
Over time, the guidelines in BCH will become part of your coding standards, and the overall quality of your work will improve, slowly, but surely
Let's keep striving for a healthier digital world!
Go to the official website for BCH and improve yours and your organization standards, one guideline at a time!