Tips to write good code while keeping a good pace
December 12th, 2020 • 7 min readClean code? What does that even mean? Should I care as long as the code is working? The client won’t even see it 😏. How clean is really clean code?🤔
“I like my code to be elegant and efficient. The logic should be straightforward to make it hard for bugs to hide, the dependencies minimal to ease maintenance, error handling complete according to an articulated strategy, and performance close to optimal so as not to tempt people to make the code messy with unprincipled optimizations. Clean code does one thing well.”
-Bjarne Stroustrup, inventor of C++
This definition can be quite vague for a novice, but more or less clear for someone who is already writing clean code. This article will teach you a few important things on how to write clean code while keeping a good pace.
“C’est au pied du mur qu’on voit le maçon”, means that you’re are being evaluated based on your craft. When you’re applying for a job, someone will likely review your past project code, and what will they look for? They don’t have time to fully review your code, so they will look for mistakes(anti-pattern, code smells, bad naming). Very bad code = Not getting hired!
There’s that theory called the Broken Windows Theory that states: “… visible signs of crime, anti-social behavior, and civil disorder create an urban environment that encourages further crime and disorder, including serious crimes”. As the code is already bad, you tend to add more bad code. The truth is: “bad code scale very badly”.
As your codebase grows so does the number of bad code, it’s like cancer or gangrene, and you will likely end up in a situation where your code start hitting real hard on performance, have to change a lot of code just to implement a feature, take you a long time to make changes because it takes you more time to figure out what the code does, or it simply can’t scale anymore!
Writing good code is an investment, at first, you might feel you’re losing time but it will save you hours, days even weeks in the future. It will be easier for you to understand that code you wrote months ago so you or someone else could build on top of it, debugging(tracking and fixing bugs/errors) will be way less painful it’s like a “find a needle in a haystack” vs “looking for a needle in well-arranged drawers”. So you go faster by writing better code.
So how can you write better, cleaner code? Here’s a non-exhaustive list of things to do.
The way you organize your package, folders, files, and code matter a lot. You don’t expect to find your socks in the fridge, right? Ok, maybe. But when you organize your files and folders you make it easier for you to modify the codebase because you know exactly where your “socks” are.
The way you organize your folders and files might differ depending on the programming languages, frameworks, or the size of the project. You can structure your package by feature for large projects, by layer for very small projects. But favor package by feature as most projects tends to grow.
//Package by layer
├── adapters
│ ├── HomeAdapter
│ ├── SignInAdapter
├── viewmodels
│ ├── HomeViewModel
│ └── SignInViewmodel
├── views
│ ├── HomeView
│ └── SignInView
├── models
│ ├── Home
│ └── SignIn
Simple, easy to navigate if the project is small.
//Package by feature
├── ui
│ ├── home
| │ ├── HomeAdapter
| │ ├── HomeViewmodel
| │ └── HomeView
│ ├── signin
| │ ├── SignInAdapter
| │ ├── SignInViewmodel
| │ └── SignInView
| model
| ├──home
| │ └── Home
| ├──signin
| │ └── SignIn
Even if this is organized by feature, there a layer separation: ui and model. In a big project, it would be easier to navigate through the various files.
You’ve probably read this somewhere: “There are only two hard things in Computer Science: cache invalidation and naming things.” Phil Karlton.
Naming things correctly is hard, but very important. Make your function, class, file name as explicit as it’s not necessary to read the whole class or function. A red flag is when you thinking about a different name when looking for a file or a function, that means that you need to refactor the name.
When you’re naming your class use a noun — class represents a blueprint of a real-world object. It’s better to use a single word to name your class, avoid using acronyms and abbreviations, and use a capital letter for the first letter, ie Car, Employee.
When you’re naming your function or method, which describes an action use an action verb + what, ie displayName, increaseTemperature, etc. It’s not a good idea to use more than 4 words in a function, keep it short and to the point.
When naming functions that return a boolean, use closed question + what, ie isFull, hasMoney, isOverheating. Careful using negative closed questions like isNotFull, since it can be confusing sometimes.
For your variables favor short words but precise, employeeName is better than just name. Think of them as labeling a bunch of drawers for a stranger who likes to ask what is inside of this and that. What do this variable holds, and what’s the context, Name of an Employee becomes employeeName.
Avoid using obscure naming or one-letter name, aaa, p, xxx 👀. Sometimes we can use a one-letter name for temporary variables that are scoped in short functions, like r for radius inside a function that calculates the circumference of a circle, or i for iterator inside of a loop.
Be consistent in your naming, sometimes some functions do the same thing but in different contexts or inside different classes, like showUser and displayUser, keep the consistency across your project.
Using these tips will force you not to create class/functions that do many things at once, your function should do one thing and do it well, that will help you to name it more easily.
Programming languages are praised for being concise, like Kotlin, Swift, Python but dreaded for being verbose like Java so does your code. Concise means clear, short, and comprehensive. Conciseness is the balance between short and clear where clear is more important.
Don’t sacrifice readability for conciseness. Why? Well, most of the time we don’t really read code, we skimmed through them, if it lack readability it will take longer to figure out what the code does and that will slow you or someone else down.
I think of conciseness and readability as the UX of code, make your code as intuitive and simple as possible.
“Everything should be made as simple as possible, but no simpler.” Albert Einstein
Commenting is very important, but comments are like using salt in cooking, use it sparingly, and don’t use it for just every recipe. We’re not talking about documentation comment but code comment.
Don’t state the obvious, let your code do that.
// Calculate the radius of a circle <- This is bad fun calculateRadius(circonference: Long) { ... }
Comment can encourage us to write bad code, the thinking goes like: “This code is unreadable, I’ll add a comment.” Comments are not there to explain what the code does, remember your code should be readable, comprehensible, with proper naming. When we use too many comments, comments that explain the what, we tend to write poor code.
Comment should be used to explain what your code can’t do which is explaining the why and should be as short as possible.
// Always use the BarFactory for creating Bar objects because it //guarantees they will be initialised
//using the correct Config. <- This is good
fun getBar() {
...
}
The what → the naming, the how → the code, the why → the comment. The why is not always necessary.
“Don’t comment bad code — rewrite it.” — Brian Kernighan
Structure your code well, so it’s easier to navigate through your files. Name your classes, functions, variables properly, add comment when necessary to explain the why, strive for readability more than you do for conciseness. If you do those well, your code will be cleaner and more maintainable.
Looking forward to the part II.
Package-by-Feature in Modularised Android Projects - Overflow Buffer