October 18th, 2021 – Reading time: 10 minutes
How many bugs did your feature cost? – An article on the value of code quality.
Keeping up high development speed, reducing bugs and creating maintainable/reusable code – If these are your goals, ‘code quality’ should be your focus.
You probably know projects that push for feature completion and are struggling with bugs, defects and performance issues. This is what a lot of software projects look like.
Having seen numerous projects and watching the same pattern repeating over and over again, one significant issue is the separation of development and quality control – either in time, in space, or both.
Practices that increase software quality
Technically software quality defines all desirable attributes of a software product. For embedded solutions these are most notably: Performance Efficiency, Reliability, Reusability, Maintainability and Size.
Performance Efficiency & Size
The performance and ROM size of the hardware are always a significant bottle neck in embedded project. So it is unsurprising that optimizing for those is common even in early stages of embedded projects.
“Premature optimization is the root of all evil in programming.”
– Donal Knuth, The Art of Programming
Everything includes a trade-off. The trade-off of optimizing performance is less reusable and less maintainable code. Performance optimization lowers readability, testability and usability – the most critical qualities in projects that experience a lot of change. Additionally, it is more difficult to identify deficiencies in code that is optimized for performance rather than readability.
“There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.”
— C.A.R. Hoare
Effective measures to improve Performance:
- Champion regular performance testing from early in the project
-> Risks can only be managed when measured
- Focus development on readability and testability
-> The development today should not be allowed to compromise development tomorrow
- Create performance unit tests for all critical units
Reliability & Maintainability
“There is no glory in prevention.”
Although reliability, correctness and defect minimization are goals of customers and users, a culture of defect prevention is as rare as they come. What can be found in most projects are economies of defects. QA is praised for finding them and developers are praised for fixing them. Because bugs are usually important and urgent, the fixes are often rushed, repeating the ‘quick and dirty’ practices that created them in the first place.
“The ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. Making it easy to read makes it easier to write.”
― Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship
The efficiency of writing code is greatly depending on developers being able to understand and reason about the code. Readability alone has obviously a tremendous impact on code comprehensibility and yet is blatantly absent in most projects. Though complexity is known to have a significant baring on every aspect of software quality, it is harder to teach and treat. Prioritizing readability and testability over simplicity allows to more easily identify and address complexity. Increasing readability and testability will inadvertently make code simpler without addressing complexity directly.
Effective measures to increase Reliability and Maintainability:
- Champion unit testing and static code analysis
- Focus development on readability and testability
-> software reflects the understanding of the developer.
- Make automated unit tests and readability checks a critical part of pull requests
- Praise defect free code and offer coachings to developers that produce defects
Most companies are building their business case on the assumption that code will be reused for similar projects. While new projects are often built on previous projects and code is reused regularly, the benefits are significantly less than what might be expected. It is common that every part of the software is adapted, reworked or even replaced for any new project. This is not only true for what is considered to be the ‘application’, but for the base software, too.
“A good design is not the one that correctly predicts the future,
it’s one that makes adapting to the future affordable.”
— Venkat Subramaniam
Reusability is by far the most complex software qualities. It requires two levels to design reusable code. The first level – the prerequisite level – requires a simple and clear architecture, reasonable code and documentation. Without the first level it is only possible to incidentally write reusable software. The second level – the reusability design level – requires transparent variant management, insights into requirements similarities and differences in several different projects, good abstractions, appropriate generalizations and awareness of the stakeholders and their needs. Most companies struggle with the reusability of their software because they skip the prerequisite level. The clarity created on the first level is needed for a proper analysis and design of reusability. Investing in that clarity will improve the degree of reuse and accelerate new projects.
“Always design a thing by considering it in its next larger context.”
– Eliel Saarinen
Effective measures to increase Reusability:
- Champion transparent and simple design
- Such a design should be easy to find
- Each diagram should describe the context
- Everything should be comprehensible without explanations
- Focus development on Readability and Testability
-> providing safeguards for developers to reuse code will make it significant more likely that they will
- Make design reviews a prerequisite for implementation
Accelerate your development today and tomorrow
Cost and deadlines are the common arguments to shy away from software quality and go for the quick and dirty hack. Yet, improving your companies, your departments, your teams, your personal software quality practices, is very likely to break even on the first project. The real reason – it seems – is neither cost nor deadlines: It is the learning and the change that is required to write better software. It is our human nature to focus on the short term that leads us to choose the stress tomorrow over the pain of change today.
The focus on the two qualities ‘readability’ and ‘testability’ will allow you to start and improve your journey to software quality with to simple steps. The benefits of readability are worth the effort from day one. Be it in design or in code. This fundamental quality will increase your co-workers and your own satisfaction and productivity. The second step – testability – is more difficult, but well worth the time and effort. Testability reduces stress and soon you do not want to development without the ease of mind that the ‘compile, test, commit’-cycle provides.
With these two qualities, the challenges of software quality will be significantly reduced.
May your next feature be bug-free.