Beginner Tips For Cleaner Code
July 24, 2020 (9 min read)
Clean code matters a lot. As a fresh programmer, it can be hard to know what clean code even means. There’s a lot of mistakes almost every beginner makes, and I’m going to address the mistakes and how to fix them here.
🤔 Why Does it Matter?
🕶 Readability.
If your code doesn’t follow a consistent set of rules, it makes it incredibly difficult to read. This means it’s harder for your peers to help you, harder for potential employers to gauge the quality of your code, and it’s ultimately going to make it more difficult for you to land that first job as a programmer.
Clean code is a massive and highly subjective subject, but the common mistakes I’m going to cover here today are not generally debated among developers although we like to pretend they matter (tabs vs spaces). They are trivial, and usually, teams will use tooling to auto-correct these problems for them.
Further on in your career, clean code, usually has more to do with design decisions and system architecture. But before you start thinking about whether or not you’re going to use a data mapper or active record for your ORM, you should probably make sure you’ve corrected these simple mistakes that most beginners do before they become bad habits.
❌ Common Mistakes
Indentation
This is by far the most common problem beginner programmers have, and thankfully it’s the simplest to fix.
Let’s first explain what bad indentation is and what it looks like.
mongoose.connect(mongoURL, function(error) {
if (error) {
console.log(error)
}
})
Notice how the code inside the anonymous function isn’t indented. I don’t know if this is objectively bad. I guess you could make an argument that not indenting looks better — the rest of your team won’t agree but fine.
Problem is though, the same person who wrote that code later goes on to do this:
render: function() {
return(<div>
<Navbar/>
{ this.props.children }
</div>)
}
Here, the author of the code decided that it made sense to indent code inside of the function. Is it because this one is not anonymous? Or maybe it’s because it’s not an if statement? Most likely, this person just didn’t really think about it, and if you were to ask them about their style choice, they wouldn’t have an answer.
Another mistake I’ll go more in-depth into later in this article is consistency, which is the main problem between those two snippets. But even if you’re consistent about indentation, there are still some cardinal rules that you shouldn’t break.
- Blocks of code should be indented once when inside another block.
Example:
// Good ✔
cleanFunction = function() {
return "This is totally awesome, 'cause it's indented properly!"
}
// Not good ❌
dirtyFunction = function() {
return "Please don't do this, it'll make a grown man cry :("
}
- Same indentation in as out.
If each step of indentation in is 4 spaces, then each step out should be 4 as well.
🐘 Here’s some PHP examples:
// Good ✔
if (isset($input->items)) {
$input->items->map(function ($item) {
return $item->cost;
});
}
// Bad ❌
if (isset($input->items)) {
$input->items->map(function ($item) { // indented 4 spaces
return $item->cost;
}); // indented 3
}
// Also bad ❌
if (isset($input->items)) {
$input->items->map(function ($item) {
return $item->cost;});
}
Whitespace
One of the code snippets above was pulled from a GitHub repository and I modified it slightly to keep it focused on the topic of indentation. But what it actually looked like is this:
// look at the line below
mongoose.connect(mongoURL, function(error) {
if (error) {
console.log(error)
}
})
Pay attention to that first line. Feels a bit claustrophobic doesn’t it? I see beginners do this all the time.
Tryreadingthissentenceandtellmehowlongittakesyou.
That last sentence was pretty hard to read right? Just like our eyes strain less to read normal text with nice spacing, code is the same.
Lets fix that:
mongoose.connect(mongoURL, function(error) {
if (error) {
console.log(error)
}
})
Notice I added some spaces on the second line too. It’s a bit subjective as to where exactly you put spaces and where you don’t but the point is you have to give your code some room to breath.
Now if we go ahead and fix the indentation we have a nice, easy to read block of code 👏
mongoose.connect(mongoURL, function(error) {
if (error) {
console.log(error)
}
})
Here’s another example (this time TypeScript):
// bad ❌
import React, { useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { Task } from './types';
import TaskList from './TaskList';
const App: React.FC = () => {
const [tasks, setTasks] = useState<Task[]>([]);
const [taskValue, setTaskValue] = useState<string>('');
const addTask = (): void => {
if (taskValue.length < 1) {
return;
}
setTasks([...tasks, {
id: uuidv4(),
text: taskValue,
createdAt: new Date(),
done: false,
}]);
setTaskValue('');
};
// more code below...
In the above example the spacing between characters, the horizontal spacing is ok. The problem is the verticle space… There are no blank lines!
Imagine if I wrote this whole article as one paragraph… Terrifying… 😨
I exaggerated the snippet a bit. A lot of beginners struggle with where to put blank lines and so usually you’ll see random blank lines in places that don’t make much sense and actually can make the code even harder to read than the example above.
Here’s how I would break this up:
// Good ✔
import React, { useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { Task } from './types';
import TaskList from './TaskList';
const App: React.FC = () => {
const [tasks, setTasks] = useState<Task[]>([]);
const [taskValue, setTaskValue] = useState<string>('');
const addTask = (): void => {
if (taskValue.length < 1) {
return;
}
setTasks([...tasks, {
id: uuidv4(),
text: taskValue,
createdAt: new Date(),
done: false,
}]);
setTaskValue('');
};
// more code below...
Some people even prefer more blank lines that what I added. But what I did is split up the code in blocks of related content. My imports are a clear section. Then my React component is easier to see. At the top of the component I setup some state, and then it’s another blank line so it’s easy to see where my addTask
function is declared and so on.
The inverse of this problem is adding whitespace where it doesn’t belong. And I see this a lot too:
import React, { useState } from 'react';
import { v4 as uuidv4 } from 'uuid';
import { Task } from './types';
import TaskList from './TaskList';
const App: React.FC = () => {
const [tasks, setTasks] = useState<Task[]>([]);
const [taskValue, setTaskValue] = useState<string>('');
const addTask = (): void => {
Usually the above problems are mixed. There’s spacing in places that don’t make sense or lack of it where there should be, indentation is weird and worse… none of this is consistent. Which segways into the next problem
Consistency
Consistency is extremely important. We could argue all day about why one style is better than another, and honestly, it happens all the time. Developers tend to have these arguments when they don’t feel like working but want it to appear like they are somehow making meaningful contributions to the project. I joke, I joke. But seriously, people have their preferences but it’s far more important that a team just agrees on a shared standard.
What really matters far more than subjective opinions is being consistent in your styles. When code is consistent, it has been proven to reduce the cognitive load on your brain while reading it1.
This matters quite a bit once you discover how much of your time is spent reading code as opposed to actually writing it.
Don’t believe me? The author of Clean Code said it so it must be true right? 🥁
“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
Seriously though, it doesn’t take long for any programmer to figure this out. We really do spend way more time reading code than writing it, so it better be easy as heck to read.
Again, this post is not covering design patterns, declarative programming, architecture or any of that. Just the simple stuff that can really improve the readability of code, and any beginner can pick up easily.
⚙ Automate It
Consistency is such an easy thing to do if you have the right tools. It’s good practice to be consistent in how you style your code, but it can be difficult to come up with all of the minuet rules on your own.
Rather than going through all of the pain of deciding between a curly brace being on the same line of a function declaration or the next line, just use a style guide that’s already made these little decisions for you and get on with coding.
There are many out there. PHP has the PSR-2 style guide, JavaScript has AirBnb’s style guide and there are many more out there.
Rather than reading through them and memorizing them, you can have your code editor format your code automatically for you instead. I have an article that shows you how to do that specifically for VueJS projects here: https://technicallyfletch.com/how-to-setup-eslint-and-prettier-with-vscode-and-vuejs
Otherwise you can lookup the default options for formatting in your editor of choice and they’ll probably work good enough for now. There’s tons of other articles out there too that will show you how to get these tools working for your specific situation.
It’s a long road from beginner to full-time developer so I hope these tips helps to make that road a bit easier to travel for you! If you have any questions or feedback let me know in the comments!
Cheers,
Dan
-
An Empirical Study Assessing Source Code Readability in Comprehension https://ieeexplore.ieee.org/document/8918951
↩