“We write code for humans to read and computers to execute”– in that order
A common topic in the software development industry is the way in which the code is written or how you should write your code. There are a lot of resources about good practices and some even contradict each other, which makes it a bit confusing. I won’t do that, instead, I’m going to show you what I keep in mind when I write code or do code reviews for somebody else.
There are many concepts that will inevitably pop-up when you study how to write and structure code. For example: KISS, SOLID, Design Patterns, Clean Code, Optimization etc. My personal favorite is KISS – Keep It Simple Stupid, but they are all valid principles.
The KISS principle states that most systems work best if they are kept simple rather than made complicated; therefore, simplicity should be a key goal in design, and unnecessary complexity should be avoided.U.S. Navy in 1960
1. Code has to execute
A baker needs to know how to bake bread. If he does not know how to do that then he cannot be called a baker. Similarly, a software developer needs to know how to write software that executes. If you are not sure what we mean by that please check the FizzBuzz challenge. What sets a baker apart is how delicious their bread is. On the same note, code differs by how efficient it is and how easy it is to read.
A common beginner’s mistake is writing too much code at once and then expecting it to run from the first try. Even experienced developers make this mistake from time to time. It is good practice to start small, see if it works, add more code and repeat. This way, if there is a mistake that prevents your code from running at least you know where to look.
Here is a basic trick that you can use if your code doesn’t work: Find your core modules and simplify or comment them out until your program executes. After it does, reverse that until you find that pesky bug. Or, you know, use TDD.
Writing code that runs is mandatory and expected of you. While this is the most important aspect of being a software developer I don’t consider it the most important aspect of elegant code.
2. Code has to be optimized
Improvements such as the garbage collector save us a lot of time and many headaches. Therefore, most of the time you don’t have to worry too much; even if you declared an array with 5000 elements. As a rule of thumb, as long as you don’t cause a stack overflow exception you should be fine.
I just said that you don’t have to worry about resources, well… I lied. My rough estimation is that for 90% of the code that you will write you don’t have to worry too much about how many resources you use. Though, it’s good practice to keep it under control. For the remaining 10% of code it’s very important to keep your code efficient. So, then the question is:
“How can I tell when I should optimize my code as much as possible?”
The answer is pretty simple honestly, you should use common sense. Try to think of the scale of your task and what your code should be able to handle. Or, you know, use the specifications document.
I’ll give you two scenarios to think about, that should help.
A) If you need to do operation xyz for:
- an array of 10 elements
- the number of elements in the array won’t change
Don’t worry too much about how long it will take. Chances are if it works it’s probably good enough for this case.
B) If you need to do operation xyz for:
- an array of 100 – 1.000.000 elements
- the number of elements can vary drastically
For B) you should worry very much.
- First of all, if the array can have a lot of elements don’t iterate it more than once.
- Having multiple repetitive structures that iterate the same array over and over again is just bad practice.
- Decide what operations you want to do with the array and iterate it only one time.
- Another great solution that I use are dictionaries and similar data structures.
- Dictionaries are your friend, my friend. Most of the time you can use a unique identifier as the key of the dictionary for quick access like O(1). Next, you can store whatever values you want as data; even a list of dictionaries (don’t ask).
I got carried away and went kind of technical above. If what I wrote above sounds like Klingon think of it like this:
If you have to carry 10 buckets of water you can do that by hand fast and easy. No need to complicate things (KISS). On the other hand, if you have to carry 10.000 buckets of water, yeah, that changes things. You need to start thinking big, you need to optimize routes and such. The secret lies in identifying when your code has to carry 10 buckets of water or 10.000 bucket (functional specifications 🙂). You don’t want to kill a mouse with a bazooka and you don’t want to go bear hunting with a slingshot. I hope these examples cleared things up.
3. Code has to be pretty
What is pretty code? Tough question, I believe each software developer has their own answer. You know how you can look at a painting and tell if it’s beautiful or ugly? You can do the same to code.
We can spot spaghetti code (ugly code/hard to maintain) by smell. Just like observing a painting, it’s not easy to identify exactly what makes the code beautiful or ugly. Some principles can help you stay on track.
First of all, avoid monolith chunks of code, the so called “God class”, that does everything. Avoid writing such a class. If you want to dive deeper into this topic I suggest you read Clean Code by Robert C. Martin. It is considered a must have book for writing elegant code.
Your code must run, yes. Your code has to be efficient, sometimes. Most importantly it has to be easy to read by fellow software developers. As long as it runs, the computer doesn’t care how your code is written. But I care Sir, I deeply care about how well your code is written. Especially if you’re gone on a two week holiday in the middle of Bum F☺️ck Oklahoma with no laptop on hand. If you can’t provide details in person, your code has to do the talking.
Here is an example of two sentences providing the same information:
Good code: Maria has 1 ring and 5 apples.
Bad code: X has z number of important stuff and y number of not important stuff.
Elegant code offers answers, bad code offers questions.
Pretty code traits:
- Reads like a sentence
- Offers clear information
- 5 – 100 lines of code
- Intuitive naming
- Short and helpful comments
Ugly code traits:
- Reads like a Sphinx riddle in the middle of the desert while riding a camel at the sunset
- No comments to help you
- Naming based on the Greek alphabet
- Huge code blocks with no line breaks – over 100 lines of code
This article covered what I consider to be the most relevant aspects when talking about elegant code. These points came to me as a result of reading about the topic, talking to other developers and seeing what actually works in a real life work environment. You may come to your own conclusions as you progress through the software developer career. You might defend a “good practice” with your life, only to abandon it completely in a couple of years.
If you skimmed through this article or you found some examples difficult to follow. This is the gist of elegant code design:
Colleague can read your code – good
Colleague has trouble reading your code – bad