Disclaimer: everything in this post is my own opinion. However, it’s 100% true and you should not question it. Let’s get started.
I love writing clean code. I want my team at Torii to write good and clean code as well. The problem is that everyone defines “clean code” differently. Here’s my non-secret formula for writing clean code that leads to less bugs, easier to change and makes me happier.
I enjoy working on codebases that focus on:
Readability. The code should be easy to read and understand. The why and how should be clear in the code.
Simplicity. Code simple. It shouldn’t dependent on assumptions you can’t read in the code. Code is simple when it is difficult to use it in a wrong way. Hard to break it when adding capabilities.
Consistent. Consistent indentation. Consistent naming. Consistent file structure. It doesn’t matter what style, paradigms and decisions were taken — be consistent.
Things I couldn’t care less about: making the code generic, forcing design patterns, the known “right way” to do it and un-needed performance optimizations.
Here’s how I code today and why.
Comments go stale and has a tendency of telling you wrong things about the code. Also, comments allows to compensate for cryptic code which shouldn’t exist. Instead of comments, focus on the code readability.
// 😞if (x > 5) { // 5 is a special point where we must run awayrunAway()}
// 👍const runAwayThreshold = 5const shouldRunAway = (x > runAwayThreshold)if (shouldRunAway) {runAway()}
Your codebase is not a project management system. JIRA, Trello, Asana (and others) are a much better fit for documented future work. Yes, even that “We must make this function faster” TODOs. If it’s a must, keep it where everyone can see it.
// 😞while (true) {} // TODO: make this code faster when we have time
// 👍while (true) {}
Using variables can help the code become self-documenting. We can use these variables to express our intent better: the variable name is the why and the assignment is the how.
// 😞if (x > 2 && x < 5) {fireMissiles()}
// 👍const enemyInRange = (x > 2 && x < 5)if (enemyInRange) {fireMissiles()}
The first line of indentation is reserved for the “Good path”. So I always break early and have the most important part of the code in the “root” of my functions.
As a general rule, less indentations → readable code.
// 😞const fetchData = (id) => {if (id) {fetch('/data/' + id)}}
// 👍const fetchData = (id) => {if (!id) {return}
fetch('/data/' + id)}
I prefer const
references over mutable references (let
or var
in JavaScript). Mostly because after I understood what a variable is once, I don’t have to think about it again. I find the small language features to support this (no matter what language it is).
// 😞let mul = x * yif (mul > 70) {mul = 70}
// 👍const mul = Math.min(x * y, 70)
Another example:
// 😞let xif (str === 'one') {x = 1} else if (str === 'two') {x = 2} else if (str === 'three') {x = 3}
// 👍const x = {one: 1,two: 2,three: 3}[str]
Reading complex code requires lots of concentration. Break complex thoughts into simple thoughts by keeping your “coding sentences” short.
// 😞people.filter(person => person.age > 10 && person.firstName.length > 2 && person.lastName.length > 4)
// 👍people.filter(person => person.age > 10).filter(person => person.firstName.length > 2).filter(person => person.lastName.length > 4)
“Wait! What about the performance change?”. I don’t care. I really don’t. Unless there’s a real world problem where the app becomes slower than expected.
I’m sure some developers will disagree with every point made.
That’s fine, but let me know why in the comments or on Twitter (@ketacode) — also checkout Torii if your company uses SaaS to operate.
If you liked this article, please Clap and share it with your network.