We’ve all seen the above image being mentioned in the context of code quality. But what do we mean when we say that a particular piece of code is good or bad?
What is Code Quality & Why it matters?
Great authors are known for writing books that tell a clear, compelling story. They use tools like chapters, headings, and paragraphs to clearly organize their thoughts and painlessly guide their reader. A developer’s job is similar to that of an author, we simply use different jargon of namespaces, classes, and methods. If authors don’t use their tools effectively, then their work will be difficult for the readers to read and understand whether it is a book or code.
Coming back to the topic of code quality, it is a set of desirable characteristics that any piece of code should possess.
- Reliability: Should work consistently without frequent crashes.
- Consistent Code Style: Should follow consistent code style and naming conventions applicable to the language
- Maintainable: Should be easy to understand. Maintainable code is easy to extend and add new functionality.
- Well-tested: Code that has well-written tests tends to have fewer bugs
- Efficient: Should not use unnecessary resources to perform the desired operations
- Secure: Should prevent coding vulnerabilities like SQL injection
- Lower Technical Debt: Having low technical debt allows teams to move fast and develop new functionality without being slowed down by low quality and non-maintainable code
The more of the above qualities that a code possesses, higher will be the quality of the code. Based on Project/Client requirements some of the above characteristics might not be required for the code.
It is extremely challenging to write high quality code when working under delivery deadlines, but it matters if you’re thinking about the long term maintainability of the code. Also, high quality code will help the teams to maintain consistent delivery speed in the long term.
Based on my experience, below are a few things that have been highly effective in improving and maintaining high-quality code in my projects.
Improving Code Quality using Static Code Analyzers
Compilers can catch and prevent syntactic issues, but they cannot detect issues like
- Inconsistent code structure
- Things that the community might have identified based on experience
- Code complexity
Static code analysis is a technique of examining the code before it is run. There are tools that can do static analysis and they work by analyzing the code against multiple coding rules. If some violations are found, these tools can be integrated into the build tools like gradle, maven, etc to fail the build.
Below are some tools that can be integrated into your projects with very little efforts:
Checkstyle is a static code analysis tool used in software development for checking if Java source code complies with coding rules. The checks performed by Checkstyle are mainly limited to the presentation of the code. These checks do not confirm the correctness or completeness of the code.
Using Checkstyle will ensure that a consistent coding style is followed by the team developing the code making it easier to read and understand.
Below are some of the checks that can be performed using checkstyle:
- Naming conventions of attributes and methods
- The number of function parameters
- Line lengths
- The presence of mandatory headers like copyrights
- The use of imports, and scope modifiers
- The spaces between some characters
- The practices of class construction
- Multiple code complexity measurements
PMD (Programming Mistake Detector) is a static code analyzer that reports on issues found within the application code.
PMD can help detect issues in the code that could cause issues when the code is shipped to production.
- Possible bugs — Empty try/catch/finally/switch blocks/eating original exception and throwing a new one
- Dead code — Unused local variables, parameters, and private methods
- Empty if/while statements
- Overcomplicated expressions — Unnecessary if statements, for loops that could be while loops
- Suboptimal code — Wasteful String/StringBuffer usage
- Classes with high Cyclomatic Complexity measurements
- Incorrect BigDecimal Usage
CPD (Copy/Paste Detector)
It can be configured to detect duplication greater than a determined number of tokens. Copy/Pasted code is undesirable as it makes the code difficult to maintain and could lead to bugs in scenarios where some change is made to one of the places and forgotten to be propagated at other places.
Measuring Code Quality
Code Coverage Metrics
Code Coverage is a metric that can be used to get some confidence about the code. Having said that, be careful in choosing which tests are used to measure the same. Not all tests from the test pyramid are the same.Tools like JaCoCo can be used to figure out the code coverage.
Only unit tests should be considered when looking at the code coverage metrics as unit tests are about testing whether the code does what the developer intended it to do and those are the ones that are the fastest ones in execution and deliver higher value.
There might be value in measuring the code coverage of integration tests, but it should be considered as separate artifact and the reports should not be combined with the unit test reports. Remember integration tests are about making sure that all the components work together. Using integration tests for increasing code coverage is like using a sledge-hammer to crack open a nut.
Toxicity Chart as the name suggests is a way of figuring out the toxicity of the code. This chart represents the toxicity of each class in the codebase based on a toxicity score that is calculated based on a set of parameters like file length, method length, cyclomatic complexity, nested statements and many more. This chart can be shown to non-technical people like business people, managers to help them understand the quality of code.
The Github repository at the link below contains a sample project with all of the above-mentioned tools setup. It is structured as easy to pick and choose which tools you require to integrate into your projects.
Maintaining code quality is a continuous process and cannot be done by a single person on the team. It is the responsibility of entire team to make sure that the code which is written is of high quality.
While the tools mentioned above will help make sure that some of the code quality aspects are present in the code, it is not the only way. Following extreme programming practices like pair programming, test-driven development, code reviews, continuous integration should be followed by teams to make sure that all the characteristics of high quality code are present in the codebase.