12 steps on writing better code
A set of handy notes on writing better code
In this article, I want to share notes that I collected from a series of many conferences and training I have attended. This article is an attempt to put them together and share it with everyone.
We all spend a lot of time reading, writing, refactoring and debugging code. So what can we do to really make our lives a lot easier? The real question is …
Why we should make the code quality a lot better?
In a typical software engineering developer life, the code we write actually has a deep meaning. Written code is like how we tell our colleagues how we feel about them. So when you’re looking at a piece of code that’s what they have left behind for you to read and how do they feel about you when they write the code.
“Does it say, say we love you when they write the code or do they hate you when they write the code.”…conference notes
That’s one of the reasons why it’s important for us to really focus on the good quality of code that we are writing and becomes very critical as well.
How often have you faced this scenario?
We want to be Agile and we always want to enhance or update our current product. You get a requirement for enhancement or fixing an existing problem in the current code. This means that you are changing the code in a spaghetti codebase and then you realize that touching that code can either disrupt the existing sophisticated codebase or the last time you touched that code you had to work for the whole weekend. And, you try to avoid this new enhancement or bug fixing.
Such scenarios always happen and now you can imagine how difficult it is to be Agile, when code quality is bad.
A great note from Venkat Subramaniam, how can we measure the quality of code.
As per him, “the quality of code is inversely proportional to the effort it takes to understand it.
If I’m spending more time on a piece of code then that usually is poor quality, if I’m spending a lot less time getting it and moving on from the code then usually would argue that it’s actually a better quality code.
I want to be spending as little time as possible to grasp and understand a piece of code that becomes extremely critical”
Steps to improve code quality
12. Identify technical debts and Schedule time to lower technical debt
In various companies, you will be surprised not many engineers and product owners don't know what their technical debt is. Ward Cunningham, provided a simple way to describe Technical debt . He tried to explain using financial industry debts. It’s as simple as knowing what’s your financial debt. You can listen to his theory in his video.
It's like you keep on accumulating debt on a credit card and fail to clear it out. This keeps on piling up until you get bankrupt…a scary scenario of course.
As just like its important to keep your credit debt clearing out on regular intervals its important to also schedule a time for resolving technical debt.
As an organization, we should be allocating time to identifying technical debts as well as resolving those technical debts. Maybe allocate certain stories per sprint for tech debt or allocate one sprint every quarter to work only on tech debts.
11. Have some SLACK time (not the messaging slack)
When you have some time to relax and slack, then it's proven that you can think and innovate more. This allows more space for innovation. Lot of organizations don’t even think about it. But its as good as having a great idea while taking shower or while going on a hike.
When you are not bothered by 10000 slack messages or tons of emails of work phone calls and just think on your own, then developers tend to think of innovative ideas and improve on problem-solving. So its important to have slack time.
10. Favour High cohesion
A well organized code with all related code under same module or file saves a lot of time for engineers to understand the flow. It helps a lot while understanding the flow and also provide knowledge to new joiners in the team.
“high cohesion= low cyclomatic complexity”… by Venkat Subramaniam
There is a good short read on the same principle
9. Program with Intention
You may have seen the code as a maintainer or contributor when you have no idea why this code was written. Sometimes, it may be possible that you were the original author of this code. This brings to a hilarious but serious problem when no one has any idea why a particular code was written, it doesn’t reflect the intention.
The code should be readable enough and should only contain what its meant to do and remove all extra bells and whistles from the code.
One of the speakers shared a funny comment which you can also find on stack overflow.
//When I wrote this, only God and I understood what I was doing
//Now, God only knows
Try to follow Beck’s Rule for Simple Design
To create better quality code, beck created some simple rules.
- Passes the tests
- Reveals intention
- No duplication
- Fewest elements ( minimalistic)
The rules are in priority order, so “passes the tests” takes priority over “reveals intention”
When we think about writing code intentionally then it forces us to really think hard on how someone will be using this code. In order to achieve all use cases its always a good practice to write the test case first before adding the main code for implementation.
8. Avoid Primitive Obsession ( Writing from scratch)
This is when we feel we have to write to code at the lowest level possible. We try to write something from scratch which could easily utilize a library or a framework, so avoid such writing of code. This saves not only time but also removes extra test cases and bugs.
“Imperative code is packed with accidental complexity”…by Venkat Subramaniam
Writing functional code is very simple but since we have been coding for a while in an imperative way, it comes very naturally to us.
Imperative style is when we have to say the same thing over and over again..as if you are talking to a toddler every day for many years.
one fo the examples could be creating variables which doesn’t do any work for us.
“A good code should read like a story not like a puzzle”..by Venkat Subramaniam
We don’t want code reviewers and new engineers to scratch their heads when they are reading your code. It should be readable in such a way that it doesn't need any documentation.
There is great documentation around this if you really want to dig deep into this topic.
Functional Style== Declarative Style + Higher order Functions
Declarative is like, what to do and don’t tell how to do it.
7. Prefer Clear code over clever code
Sometimes you may have written code when you felt really good. It feels good to your ego and coding angles over your shoulder gives a pride. But in reality, you may have written a code that may take forever for a reviewer or a new engineer to understand.
“Programs must be written for people to read and only incidentally for machines to execute”… Abelson and Sussman
Also if you are writing a code on top of existing code then try to have an intention of simplifying the code and not just follow exactly what’s already there.
“Most of the time we write ugly code to be consistent, just joining the herd”
6. Apply Zinsser’s Principle principle
This principle applies to writing well nonfictional articles, stories…may be code as well. Here are some of the key rules and it doesn’t need any explanation.
Simplicity
Clarity
Brevity
Humanity
5. Comment on Why, not on What
Don’t comment to cover up bad code. Come back to the code again and see if a junior developer can understand it or not. Think of it again.
Write expressive self-Documenting Code
“A good code is like a good joke.”
Remember when you tried to say a joke and no one got it? and then you have to explain it properly. A bad code is also like that.
If you get the same feeling when someone doesn't get your code, then pull back and check if you would like to refactor the code so that it can be read and understood. Remember it can be an iteration.
4. Avoid Long functions
Long functions are painful. When we use long functions it becomes really really hard to understand what the code is actually doing there. Some of the key pain points are
long functions are hard to understand
long functions are hard to test
long functions read to duplication
Long functions are hard to reuse
Have a Single level of Abstraction, not look length of code but look at the width of the code i.e. indentation. remember we used to write nested for loops again and again?
3. Give Good meaningful names
Please do not create variable names with something like i, j , x , y. Have a habit of giving meaningful variable names. Once you get into the habit of writing good variable names things automatically start falling into place like a first step in writing good code.
“variable names represent abstractions.
If we can’t name a variable or function appropriately, it may be a sign we’ve not understood its true purpose”
2. Do Tactical code reviews
Sometimes engineers get offensive when code review happens. It should not be taken as a practice to blame others or prove their superiority. Code reviews help in talking the same pattern of writing code among engineers, helping learn new ways and also challenge on conflicting styles.
Also, its a good habit to review test cases, it makes sure that tests are written for the code.
Try to submit your code in small segments i.e raise a pull request (PR). A good article is around this
Peers reviews can catch a lot of defects and it also complement testing.
1. Reduce state and state mutation
Try to write the code only when its required, add just enough code what’s it required for.
As every line of code is a liability for the organization.
Experience teaches us try not to write a lot of code it teaches us to remove the unnecessary code and keep it simple.
This is all I have from speaker notes and series, I hope you enjoyed this article. Finally, I want to share a good tweet from Venkat Subramaniam.