Nine Common Traits and Ways of Identifying Bad Code

From experience, bad code is often born out of the desire for instant gratification. Instead of writing a couple of extra lines of code and being more intentional with how we structure our code, we just love copy and pasting solutions on the internet to reach our goal.

Why? Because it is easier, quicker and more convenient.

This post is aimed mostly towards new developers. Developers who are new to the game are mostly focused on just making things work. While not inherently bad, without guidance, new developers can quickly develop bad habits that will set them back in the long run.

This post aimed at opening the eyes of developers by pointing out common code smells. Also common actions and habits of that usually result in bad code. Before the desire to see some visible results degenerates into bad coding habits.

To those that are interested, prepare to feel the sting!

1. Bad Code is difficult to understand

Ask your co-workers the following questions

Read this piece of code. After you finish reading,

  1. Can you tell me what it does?
  2. Did you find the code easy to follow?

Bad code creates confusion. Good code is self-explanatory.


2. Duplicate Code

Every heard of the acronym DRY? It stands for Don’t Repeat Yourself and it is almost exactly what it means. If a piece of logic is repeated at least once, it is generally a good idea to place that code inside a function for reuse.

Of course, this is just a generalization and there is more to DRY than just extracting duplicate actions. But it is a great and most importantly, simple way to start chipping away at the habit of writing duplicate code.

In The Pragmatic Programmer, we have the famous quote on DRY

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

In essence, this rule states that we should divide our code into clear parts, where each part is responsible for a specific role. As humans, we are bad at managing complexity.

Keeping duplications to a minimum allows us to better manage complexity, especially as the software grows in size. I know DRY is a way more complex topic at that, but for starters, removing duplicate code and making sure that you place common operations in its own separate function is a start.

don't leave your code out to DRY - don't repeat yourself


3. Copy and Pasted Code

i will not copy and paste code

Below are two major reasons why people copy and paste code.

  • It is a quick way to get something working properly (E.g. code snippets from stack overflow).
  • To import and use a feature that you require, but don’t know how to build on your own.

Although it may seem harmless, guess what copying and pasting from your own code base violates? My eyes are getting a little DRY here.

Importing a feature that you need from the internet is not always bad. We do it with libraries all the time. By using libraries, we don’t always have to reinvent the wheel.

However, this practice becomes harmful when you copy and paste without understanding or attempting to understand what the code is doing behind the scenes.

Using code written by somebody else without understanding how it works is the same as using a hammer without knowing what it is built for.

Much like submitting a plagiarized article for your high school assignment, you will gain nothing from just simply copying and pasting a solution from stack overflow. Remember, you are not coding simply to build something. With each project, aim to grow from it.


4. Code produced Absent-mindedly

Do not go on auto pilot mode

Do you ever catch yourself writing code with the same focus and state of mind as though you talk about how your breakfast tasted?

Once you have gained some confidence, it becomes natural to write certain code without thinking. If you write console.log() or std::cout 10,000 times, it is often natural for your brain to shut down while writing those lines.

Familiarity is the number one enemy of programmersClick To Tweet

Coding absentmindedly is like drunk driving or speaking without thinking. Programmers are problem solvers. Therefore, absent-minded problem solving, unless solving something very simple, will naturally result in imperfect solutions. When working on larger projects, something “small” as absent-minded coding can cost you dearly.


5. Settling Immediately on the First Solution

this should work okay start coding

One of the tendencies of beginning developers is to be ecstatic when they come up with a solution. That is not a bad thing. I remember the euphoria that I felt when I wrote my first sorting algorithm. Little did I know at that time, that the algorithm written by me was already invented and had a Big O of O(n ^ 2). In other words, bubble sort.

In programming, there are more than one ways to solve the problem. If you have a shallow understanding of the problem domain, it is only natural for you to be able to come up with shallow solutions. That is okay.

What is not okay, however, is to settle for that shallow solution.

If the performance is/has the potential to be a problem in the future, every programmer should seek to find answers to the problem.

What are some problems with this solution? What can I do to overcome this problem while preseving its functionality?


6. Naming Variables X, Y, and Z

Okay, that was an exaggeration. However, providing vague, verbose names to your variables is the same as naming them a,b,c,d if not worse.

Coding is writing your thoughts down for computers to run and developers to read.Click To Tweet

If you were drawing up a floor plan of your house, will you label the kitchen and living room A and B?

When you work in a team, your code should serve to accurately inform the next developer on how a particular problem was solved. Verbose, confusing and undescriptive names act as hindrances and will leave readers frustrated.


7. TODO: Refactor Later

// TODO: Refactor and separate parse and show
function parseDataAndShow(data) {
   // some logic here
}
// 1 month later ... 
// Why did I need to separate this again??

I believe every developer is/has been guilty of leaving a comment that involves doing something LATER at one point in their career. Including myself. When you write comments like this, how many times has this TODO sat in the code base for more than a month, unattended?

Procrastination is the bane of productivity.

If that TODO is left unattended for a whole month, it is highly likely that all the background information or courses of action would be long forgotten. Unless the background information and unique details were well documented.


8. Using Documentation to Justify Bad Code

One of the traits of good code is that it is self-documenting. In other words, the code itself E.g. the variable names, method names, clear logic, etc. clearly explains to the developer what is going on. In contrast, bad code is littered with unnecessary comments. Something like the following

/**
 * Add and return the sum of
 * num1 and num 2
 */
function sum(num1, num2) {
    return num1 + num2;
}
Comments in code should exist to explain things that code cannot. Click To Tweet

For example, history. Good comments can be used to log the background history, events or user-requirement changes that resulted in a particular piece of code being refactored in a certain way.

Another tell-tale sign of bad code is if your code is so confusing that you need comments to explain what your code does.

If this is the case, do not delay in refactoring. Otherwise, it will come back to bite you in the butt.


9. Spaghetti Code

spaghetti code is bad code - twisted and difficult to follow

Spaghetti code is twisted and tangled, much like spaghetti. It jumps all over the place. Ever tried to straighten out each piece of noodle? Debugging spaghetti code is like straightening out all those noodles. Absolutely frustrating.

In order to avoid spaghetti code, write functions and classes that are responsible for one thing. In other words, they should only have a single reason to change. The following function

function handleResponseAndErrorAndDisplay() {
    // logic for three different and separatable actions here
}

should most likely be refactored. Having three different actions intertwined together creates some nasty, unnecessary dependencies in the future.

Spaghetti code is a problem because the flow of logic is difficult to follow. Code that reads like code will eventually cause problems in the future when you have to update, debug that piece of code.

Avoid WET (write every twice) code. Keep the code DRY.


Want more items added to the list?

If you have any suggestions on bad code and how to identify bad code, feel free to leave a comment. I will add it to the list.

For a more in-depth read on code quality, I recommend checking out my post on a critical analysis of both bad and good code,. Mind you that the article is fairly lengthy.

Hope you enjoyed the read and happy coding guys!

About the Author Jay

I am a programmer currently living in Seoul, South Korea. I created this blog as an outlet to express what I know / have been learning in text form for retaining knowledge and also to hopefully help the wider community. I am passionate about data structures and algorithms. The back-end and databases is where my heart is at.

follow me on:
7 Shares