DEV Community

Paul Akinyemi
Paul Akinyemi

Posted on • Edited on

A beginner's guide to writing cleaner code

Why should anyone even care whether their code is 'clean' or not?

Indeed, 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. ...[Therefore,] making it easy to read makes it easier to write.
― Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship

I think he put it rather nicely.

So we know why we should care, but what exactly is clean code? What separates clean code from messy code?

This is the answer I prefer: "code is clean when it's easy to read, easy to understand, and it's organized in a way that makes sense to other people".

Now that we have a definition, what exactly can you do to clean up your code? I've outlined my best advice below:

Making your code easy to read

Whitespace is your friend, and too much whitespace is far better than too little

Text, in general, is much easier to read when it's generously spaced, but it tends to feel overwhelming when it's too dense. Dense blocks of text also make it harder to keep track of your position in the document.

To illustrate, here's some dense code:

import function from module
variable = function(argument)
variable = function(variable)
def my_function(argument):
   do xyz
variable = my-function(variable)
Enter fullscreen mode Exit fullscreen mode

And here's some well-spaced code:

import function from module

variable = function(argument)
variable = function(variable)

def my_function(argument):
   do xyz

variable = my-function(variable)
Enter fullscreen mode Exit fullscreen mode

See how some space makes it easier to read?

The length of any line in your code shouldn't exceed 80 characters

Your code will be easier to read in many short lines, instead of a few very long ones. There's nothing magical about the 80 character limit, but I find it a convenient rule of thumb, and anything much longer quickly becomes a pain to read.

Making your code easy to understand

Writing too many comments is much better than writing too few

Comments can sometimes feel bothersome to write, but whenever you write any code that is even slightly complicated, you should have a short comment before it.
The comment should explain what you were trying to achieve and if it's a very complex piece of code, briefly documenting why you chose that approach might be a good idea.

Long identifiers are better than cryptic ones

Sometimes, it feels hard to express the purpose of a variable or a function in one word, and writing a multi-word variable name can feel awkward.
But it's still better to use a long name that clearly explains the purpose of a variable than one that is short but cryptic.

Avoid nesting where you can(but keep line length in mind)

This:

if x and y and z:
   pass
Enter fullscreen mode Exit fullscreen mode

is easier to understand than :

if x:
  if y:
    if z:
      pass
Enter fullscreen mode Exit fullscreen mode

but this:

if black and white and blue and red and green:
      pass
Enter fullscreen mode Exit fullscreen mode

is harder to understand than:

if black and white and blue:
  if red and green:
    pass
Enter fullscreen mode Exit fullscreen mode

Organising your code

As much as is reasonable, DRY(Don't Repeat Yourself)

When you find yourself repeating the same(or very similar) code in more than two different places, you would usually be better served turning it into a function and calling it twice instead. Your code ends up being shorter, and making future changes becomes much less of a hassle.

Side effects are evil, so use with (extreme) caution

Some functions accept parameters and return a value, and do nothing else. That's what an ideal function looks like. Impure functions cause side-effects: changing a global variable or class attribute within the body of the function, for example. Side effects are evil because they generally make debugging a pain in the behind: You end up having to scrutinize each line of code to understand where the heck the value of your variable is coming from.

Your functions should ideally do only one thing

Functions that have more than one job are usually much longer than they should be and tend to cause much confusion in the code you're calling them. To use an analogy, if you asked a friend to grab you a book and he returned with a shoe in his other hand, wouldn't you be really confused? It's the same idea with your functions, so please don't confuse the poor folks who end up using or changing them. Your function should do what its name says, and nothing more.

Summary

  • Keep it short
  • Space it out
  • 80-character lines
  • Write lots of comments
  • Use good names
  • D.R.Y
  • Pure functions
  • Simple functions

Putting it into practice

No one keeps an eight-step checklist in their head as you're trying to solve a problem or fix a bug, so how does anyone manage to write clean code? Simple. We don't, at least not at first. The answer is called refactoring, and it means changing code without affecting the output.

After you're done with one piece of code, stop. Take ten minutes to breathe. Look away for a little while. Then go over the code you just wrote, and fix any messy bits you find.

Over time, writing clean(er) code will become more and more of a habit, and you'll find progressively fewer mistakes when you refactor.

Further Reading

I tried to make this post as useful as I could, but a full, in-depth treatment would probably require writing a short book. Here's some extra content you'll find useful if you want to learn more about writing clean code.

Top comments (9)

Collapse
 
samuelfaure profile image
Samuel-Zacharie FAURE • Edited

Good TLDR, I would add two things tho:

  • 80-character lines: There is no good basis for limiting to 80 characters a line.

Historically, this value comes from the fact that IBM punch-cards had 80 holes in a row. Because of this, our first terminal screens could display 80 chars on a line. We have great screens today and 80 chars is just too short, since one often have to sacrifice other principles of readability (i.e good naming) to respect this limit.

I find the sweet spot to be a hard limit of 120 chars a line, with a soft limit at 100.

  • D.R.Y: Good advice for very early beginners, but it should always be said that a little repetition is usually much better than added complexity. D.R.Y should be a very flexible guideline.
Collapse
 
morgenstern2573 profile image
Paul Akinyemi

Thank you for the additions!

I didn't know that about the 80 character rule, nice

A little repetition is much better than unnecessary complexity...fair enough

Collapse
 
eljayadobe profile image
Eljay-Adobe • Edited

Clean Code is well isolated. Which means that the code exhibits high cohesion and low coupling.

If the code is unit tested, it means the code must be isolated to be unit testable.

Having unit tested code squelches spooky action at a distance behavior.

Having unit tested code also suppresses emergent behavior. And acts as developer pressure to abide by SOLID principles.

Having unit tested code also means the code can be refactored aggressively and with confidence.

Code that is not isolated, is not clean. It is hard to reason about. It is hard to change. It is easy to break (i.e., introduce bugs) when changing. Code that is not isolated has highly intertwined coupling, which is why the code is hard to reason about, hard to change, and easy to break.

The enormous value of unit tests is that they validate the code is isolated.

Note: DRY is great for code, not so good for unit tests. Unit tests should follow the Write Expressive Tests (WET) principle; they should be independent from one another, avoid common setup/teardown, no loops or branches, and follow the arrange-act-assert pattern.

Collapse
 
morgenstern2573 profile image
Paul Akinyemi

Thank you for the detailed addition!
I agree, unit testing is very good practice

Collapse
 
tomquincy profile image
Tom Odey

Good article. Very nicely written. I especially dig the conclusion. Some pure honesty in there!

Collapse
 
paulonteri profile image
Paul Onteri

Great read!

Collapse
 
morgenstern2573 profile image
Paul Akinyemi

Thank you!

Collapse
 
jemeni11 profile image
Emmanuel C. Jemeni

Amazing 👌

Collapse
 
morgenstern2573 profile image
Paul Akinyemi

Thanks, boss!