Pretty on the Inside
Why clean code matters to your customers
I’m a big fan of tools like style checkers and test coverage reporters that help me write clean looking, well tested code. While these tools have a tangible benefit to me, these advantages can sometimes be overlooked by the product owner. Many times, the product owner(s) of a software project will be uninterested in low level technical details like these, so spending time on style checking and unit testing may seem worthless to them since end users do not see the code.
I would argue that these exercises have value for both the developer and product owner.
Enforcing code formatting rules makes me more productive because the resulting code is easier to read and understand. My first project assignment after getting my engineering degree was a rather large C project where the entire program was just one function:
main(). I “wasted” almost an entire work week trying to understand the tangled mess of code enough to begin working on the requested changes. In contrast to this, most of the projects I’ve worked on at MichiganLabs have been orders of magnitude larger than that first project but I typically need to spend only a few hours to get up to speed on how things work. This productivity boost is also palpable for continued development and code reviews because well organized, loosely coupled code can be modified or reviewed in smaller sections.
Poor code style can also lead to defects in your code. Many style checkers have the ability to check more than indentation and bracing style and are able to inform you of unidiomatic design or code that is overly complex. A great example of how poor code style led to serious defects is the uncontrollable acceleration caused by the “Bowl of Spaghetti” code in the 2005 Toyota Camry. An investigation of the vehicle’s source code found numerous violations of MISRA rules (the industry accepted coding guidelines):
For every 30 rule violations, you can expect on average three minor bugs and one major bug. … Barr checked the source code against MISRA’s 2004 edition and found 81,514 violations.
Toyota’s software team failed to follow industry standards as well as their own internal standards which led to costly defects and loss of life. Most projects won’t have such dire consequences for defects but poorly written code will have a negative impact on end user experience which is undesirable for any product owner.
I’ve also found that measuring and striving for increased unit test coverage yields benefits similar to those given by using code style checkers. One of the primary benefits of software testing is that it can prevent defects in new code and ensure that previously mended defects which have been mended remain fixed. An IBM study (Capers Jones, Software Assessments, Benchmarks, and Best Practices, 2000) found that:
Software defect removal is actually the most expensive and time-consuming form of work for software.
Additionally, I’ve found that writing unit tests has a positive impact on the style, structure and quality of my code. Code that is too tightly coupled and overly complex can become untestable (this was the case with the Toyota Camry source code).
A good example of how lack of testing allowed a simple but serious security defect to be released is the “Goto Fail” bug in iOS 7. The offending code is rather simple:
<span class="k">if</span> <span class="p">((</span><span class="n">err</span> <span class="o">=</span> <span class="n">SSLHashSHA1</span><span class="p">.</span><span class="n">update</span><span class="p">(</span><span class="o">&</span><span class="n">hashCtx</span><span class="p">,</span> <span class="o">&</span><span class="n">signedParams</span><span class="p">))</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="k">goto</span> <span class="n">fail</span><span class="p">;</span> <span class="k">goto</span> <span class="n">fail</span><span class="p">;</span>
The problem is that the second
goto fail is always executed if the first one isn’t. However, if there is no error to report, the code reports success instead, even though subsequent important security checks have not been performed. This defect could have been avoided if the developers head written even rudimentary tests for the expected behavior of these security checks. Even a simple code style check would have caught the wrongly indented statement and called the developer’s attention to it.
Where the Rubber Meets the Code
I sometimes struggle with being able to justify the value some of these clean code exercises to the product owner. I’ve found that it helps to share some of my personal experiences of how clean code has led to increased productivity and less defects as well as the more shocking examples of bad code mentioned earlier.