Don’t Be a Goofus: Keep Your Code Clean

“Clean code helps make our lives as engineers easier,” said Wyze’s Tim Mai.

Written by Avery Komlofske
Published on Nov. 02, 2022
Brand Studio Logo

Goofus and Gallant — comic book characters first created in 1940 — were written to show the right way and wrong way to behave. True to their names, Goofus would always miss the mark in his efforts, while Gallant would succeed with flying colors.

Let’s pretend that Goofus and Gallant are both modern-day software engineers.

When working with code, Goofus uses “magic numbers” that seem to come out of nowhere. Gallant’s numbers are always tied to a specific variable. 

Goofus’s pointers are inconsistent, making it harder to find bug locations. Gallant’s are constant. 

Goofus has to fill the code with excessive commentary to make people understand. Gallant’s comments each have purpose — his code is clean enough that its logic is self-evident most of the time.

Which one would you rather work with? 

For Tim Mai, software engineer at user-centric smart home technology company Wyze, the answer is easy.

“Clean code helps make our lives as engineers easier,” said Mai. When an engineer’s code is easy to understand and change, it elevates the team’s ability to solve problems and implement new ideas — rather than wasting time attempting to decipher one engineer’s hieroglyphic lines and comments.

Keeping code clean, on a team and an individual level, takes practice and intention. If an engineer lets themselves fall behind on the practice, it’s easy for code to become overwhelmingly clunky. As such, Mai sat down with Built In Seattle to talk about the “Gallant” principles and practices his team lives by — and the ones they avoid — to keep code communication clear and easy.

 

Image of Tim Mai
Tim Mai
Software Engineer • Wyze

 

When it comes to writing clean code, what are some best practices you follow, and why?

Most of the practices I follow ultimately stem from the book Clean Code by Uncle Bob. The principles I use ultimately lead to code that is maintainable and scalable.

I prioritize four main principles.

First, meaningful names, which act as a form of self-documentation, make reading code more like a book and errors easier to find. Long names are okay, as long as they mean something.

Second, minimizing function parameters is critical — the more parameters there are, the more difficult it becomes to understand the purpose of each input. If they’re also the same data type, or if the language is typeless, you’re much more likely to mix up inputs when calling the function. If there are three or more parameters, they can be grouped into a data type.

Third, focus on abstraction. Hiding certain implementation details emphasizes the most important parts of a function. It also continues to improve readability.

Fourth, lean into comments and documentation. Self-documenting code is great. As new changes are made, this reduces the occurrence of comments becoming outdated and requiring updates. There still need to be comments which explain or clarify intention or purpose, but documentation should not be used as a crutch for poorly written code.


 

On the other hand, what are some bad coding habits that you wish every developer would stop doing, and why?

Besides doing the opposite of the previous principles, there are two practices that are fairly detrimental.

First, using “magic numbers” — hard-coded values are necessary when programming, but they should always be tied to a constant variable or macro. This helps the code become more self-documenting and it’s easier to look the constants up and change them — or just confirm they’re correct. I’ve seen magic numbers which delayed my complete understanding of the code by days, or even weeks, because I had to reference other codebases or documents to figure out what the numbers referred to.

Second, using non-constant pointers — if an address space doesn’t need to be modified, pointers should always be constant. This prevents an erroneous modification of the data and makes it immediately apparent that it won’t be modified. This is especially true if the pointer is an input to a function. If there’s a bug with some data being modified and it’s being passed as a constant reference into a function, I know that it’s much more likely the problem is in another location instead of within the function.

Putting in effort for clean code not only means we care about the customer, but also about each other as team members.”

 

How does your team make clean code a priority? What are the benefits of this approach to software development?

Developing clean code doesn’t occur overnight. It takes time at both the individual and team level. Individually, we each put forth an initial clean design prior to a merge request. As a team, we are willing to review the code closely and provide the constructive criticism necessary for the best result. These efforts ultimately stem from our value of being "too good to be true,” because the purpose of developing great code is to ultimately create a product which exceeds the customer’s expectations. 

Additionally, it makes it less frustrating to resolve bugs and develop new features. Putting in effort for clean code not only means we care about the customer, but also about each other as team members. It becomes easier to foster professional development and even attract new talent.

 

Responses have been edited for length and clarity. Images via listed companies and Shutterstock.