Sponsored By

What Does Good Code Look Like?

Good code is readable, simple, and testable. Does your code fit the bill?

Jacob Beningo

January 16, 2024

4 Min Read
What Does Good Code Look Like?
Mohamad Faizal Bin Ramli/iStock/Getty Images Plus via Getty Images

At a Glance

  • While the notion of "good" code could be considered subjective, there are some aspects you could measure

There is often pressure on embedded software developers to develop “good software” or “good code.” The problem is the idea of good code is often subjective. What I consider to be good code might be different from what you think to be good code. Developers often consider the code aesthetics and the style of the code, which may or may not result in good code. In this post, I’ll share with you what good code looks like and the characteristics that it often exhibits. 

Good Code Is Readable

Let’s get straight to it. Good code is readable by a human. As a developer, you should be able to read your code and your colleagues' code and understand it! While readable code may seem obvious, it’s incredible how hard it is for embedded software developers to write it. The key to writing readable code is to leverage white space. 

White space is the empty space around your code, like spaces, tabs, and new lines. Developers often view white space as evil because they feel intelligent developers use the fewest lines possible. That is incorrect! Brilliant developers use as much white space as needed to make their code readable! 

Here’s an example of an extreme example of unreadable code.

Following is a simple program that prints out a result in two lines of code:

Related:5 Tips for Becoming a Successful Embedded Software Architect

#include<stdio.h>

int main(){int a=5;int b=10;if(a<b){printf("a is less than b.\n");}else{printf("a is not less than b.\n");}return 0;}

You can figure out what the program does, but spotting problems takes time and effort. Take that example versus the following:

#include <stdio.h>

int main() 

{

    int a = 5;

    int b = 10;

    if ( a < b ) 

    {

        printf ( "a is less than b.\n" );

    } 

    else 

    {

        printf ( "a is not less than b.\n" );

    }

    return 0;

}

The second example not only uses spaces and newlines but also adds extra spaces in function calls and new lines for brackets. The code uses more lines and is less compact. However, it’s easier on the eyes and less likely that a reviewer will miss something. 

Good Code Is Simple

When code is simple, it’s readable and less likely to have bugs. Bugs can be injected into a function when it is written or when it is modified and maintained. The more complex a function, the higher the likelihood of bugs. Developers should strive to write many simple functions that work together to accomplish a more prominent, complex feature. A function should do one thing. 

While keeping code simple makes sense, it’s harder to do in practice. One technique I often use is measuring the Cyclomatic Complexity of every function in my code. Cyclomatic Complexity is a measurement that tells developers the number of paths through a function. It’s been shown that ten or fewer paths are considered a simple function. More than that, the statistical probability of a bug existing or injecting a bug during maintenance dramatically increases.

Related:5 Effective Strategies You Should Know to Avoid Debugging

Good Code Is Testable

You can often recognize good code because it will be testable code! You’ll often find that a series of tests are automatically executed to verify that the code is meeting its requirements. Testable code will exhibit characteristics like:

  • Managed dependencies that decouple the hardware and leverage dependency injection. 

  • Well-defined interfaces that provide clear interaction points with the rest of the program.

  • They are easily executed in an automated test harness on a host machine.

One mechanism developers can use to ensure they have the correct number of test cases is to leverage Cyclomatic Complexity measurements! Yes, that’s right! They can be used to ensure you have developed simple functions and have the minimum number of test cases required, too! Since Cyclomatic Complexity measures the number of independent paths through a function, that number also provides the minimum number of test cases you need to test that function and cover all paths. Additional test cases could still be required to cover boundary conditions, but at least all paths are covered!

Testing does not guarantee that your software is high-quality, but it can elevate the reliability and quality of your software. Good code is always associated with a good set of tests that help developers ensure that the code behaves as it should. You’ll rarely find good code that doesn’t include a suite of automated test cases to go with it.  

Conclusions

Good code is readable, simple, and testable. While readable does require a definition or a style to ensure developers are on the same page, simple and testable don’t. You can measure your code to determine if it is simple and testable. Once you’ve defined what readable means, you can probably use static analysis or AI tools to determine if it’s readable, too. 

You may find other characteristics that can be used to define good code, such as modularity, scalability, and so forth; these are the big ones. If you can adjust your processes to define and measure them, you’ll find that you can consistently deliver “good code.” 

About the Author(s)

Jacob Beningo

Jacob Beningo is an embedded software consultant who currently works with clients in more than a dozen countries to dramatically transform their businesses by improving product quality, cost and time to market. He has published more than 300 articles on embedded software development techniques, has published several books, is a sought-after speaker and technical trainer and holds three degrees which include a Masters of Engineering from the University of Michigan.

Sign up for the Design News Daily newsletter.

You May Also Like