Writing good code.
Lately we have been seeing a lot about clean code, a code that is easy to read and maintain, a code that is elegant and even more important, that won’t make other programmers loose their mind reading/maintaining it.
This post is about basic changes we can do to make the code we create more elegant and easy to understand.
A good start would be reading this book, Clean Code: A Handbook of Agile Software Craftmanship, but if you want something more summarized I will describe here 5 tips.
- Meaningful Names
When I first started to code I didn’t like variables and methods with big names. I used to code within bad IDE’s and big names made things more complicated, but I was wrong.
The name’s length of your methods/variable is not a big deal(when coding in a good IDE), the most important is the choose intention-revealing names, this will help who is reading your code to have an idea of what it is about. A BAD example would be:
What does it mean ‘d’ in real life? Imagine that this variable ‘d’ is being used somewhere far away from its initialization, the reader would have to go back to its initialization and read the comment to understand what this variable is about! This is not time effective.
Try to choose pronounceable names, we are good at recognizing words, how to read ‘gtmsp’? I would rather read:
Choose one word for concept, see the following example:
In one method we chose the word ‘fetch’ in the other we chose the word ‘get’. What is the difference between these methods? Aren’t they doing the same action? When we read different names/words we tend to infer that they are doing different things which may lead to miss interpretation. If the methods are doing the same action/concept choose the same word to this action.
- Do one thing! No side effects!
Sometimes we create methods that do more than one thing and we don’t even realize that, see the following method:
Even though this method is small and with intention-revealing names, it is doing more than one thing and there is a side-effect(login) when calling it. It could bring to unexpected results in case a developer decide to call it just to ‘validateCredentials’ because it is not obvious that this method is making a 'login'. A more elegant solution would be:
Now the method ‘validateCredentials’ is only validating credentials, no side effect.
- Blocks and Abstraction Levels
A clean method do not have a lot chaining blocks(if/else/while) instead it should have a low cyclomatic complexity. A method that have only 1 or 2 blocks is easier to read since there are less paths to follow. This way the code is less susceptible to errors making it harder for bugs to hide.
Every method should only have one abstraction level, see the example:
This method has different abstraction levels. There is a high level concept, the static constructor ‘Note.from’ and also a call to a ‘server.saveNote()’ which means that the implementation of this concepts is hidden from us, we don’t really need to understand it.
There is also a low abstraction level, the method ‘append’ is modifying a String by appending a ‘\n’ and the 'date' into the original String, we can see the real implementation here, it is not hidden.
When you mix different levels of abstraction the method becomes more difficult to read.
- Methods Parameters
It would be very good if all the methods we call didn’t have any parameter, we wouldn’t have to worry about its type, default values, state and so on.
So try to build your methods so they require the least parameters as possible. If one method requires more than 3 parameters probably it is doing more than ONE THING, so try to break it into smaller methods. See the following example:
This method is small and clean but it is using its 4 parameters, how to remove the need of all of them?
Create an ‘Argument Object’, that is an object that holds this 4 parameters, see the result:
What are the benefits of an Argument Object? Imagine that the method ‘scheduleRomanticDinner’ is being called 100 times within the code, what would happen if it was required to add one more parameter? This method would have to be rewritten 100 times. Using a Argument Object this change will affect only the object initialization.
- Size matters!
The last but not the least: SIZE. Seriously, is there something worse than trying to find a BUG within someone’s big messy method? Every time it happens I always think about rewriting the method but then the size reminds me that it may be doing things I would never imagine.
So make your methods small! How small? Smaller than you think!
In the book the author says that hardly your methods would need more than 20 LINES. I try to follow this bounds and I feel like they become easier to read. Break your big methods into smaller ones. It is not that difficult ;)
All this practices aim to make it easier for your code to be extended and read. We know that new requirements will come up and scopes will be changed. We can not allow that small changes affect the structure we have built. By the end of the day changes are one of the few certainties we have in Software Development.
If you like Android Development, take 5 minutes to learn more about MVP (Model View Presenter) Architecture.