Reading and Learning 'Clean Code' by Uncle Bob #Day_5
Understand clean code with me and become the clean coder
Welcome to Day 5 of the clean series. On Day 4 we discussed Chapter 2 of 'the clean coder', today we are going dive into insights from Chapter 3 of 'Clean Code'. On Day 3 we covered chapter 2 of 'Clean Code' which was about 'Meaningful names', today we are moving one step ahead towards 'Functions'.
Before we begin, let's make a mindset. Understand that what we are learning here are clean and efficient practices. We are exploring ideas and easy implementation of those ideas. Merely reading will neither make you a clean coder nor make your code clean. That's right, actions are required, constant practice is required to master the clean art. Start applying these principles to your projects and collaborations, and watch the magic happen. (what a cliche way to say it, I hope you get my point).
Chapter 3: Functions
Functions are often defined as the block of code we use multiple times just by calling the function at the desired point. Indeed, functions have been a primary part of programming. It is the oldest concept to survive among its contemporaries and they are everywhere. No matter what you do, you'll find a place to fit a function in.
Without further ado, let's quickly go through my findings:
Functions should be small, and then they should be smaller than that. Here, the writer means that when you create a function, make it small and no fancy number of lines. Then when you come back to your function after you already wrote it, make it even smaller. Go through it again to see where you can cut those extra lines. The writer doesn't have an evidence to support this theory but he merely speaks on his experience and after reading the book so far. I value his experience. Further points will make it clear how to make a function small and cute.
When another person reads the function you wrote, they should be able to get the exact logic of the function and each line should hold meaning. What I understand by this is, to avoid redundancies. Avoid repetition and unnecessary lines.
Too many indentations? Complex nested loops? You don't need it. Remove them. They are not easy to look at and this would rather mean that your function is doing more than one thing. You really don't need four loops nested into each other. To me, even three is too much.
Do one thing. Your function should be indivisible. If you're able to derive another function from the previous, that is not merely a restatement of its implementation, you're function is doing more than one thing.
Functions should do one thing. They should do it well. They should do it only.
- Uncle Bob
All functions should be at the same level of abstraction. Otherwise could be confusing.
One level of abstraction per function. This is a way to make sure your function does only one thing. And each function should introduce the next abstraction. This also promotes that we should highly care about giving a good structure to our programs. Notice how this advice feels like inclining towards procedural programming. It doesn't mean we can't use these in OOP in our way. Can you think of ways we can apply this to OOP?
Switch case statements should be avoided and used only with polymorphism. These statements should be buried in low-level class and shouldn't repeated. This is because of the nature of switch statements. It is difficult to make them do just one thing. They should be used quite less, used to create polymorphic objects and hidden behind an inheritance relationship.
SOLID principles shouldn't be compromised. If you are not aware of SOLID principles, I would highly suggest studying and practicing them. They'll make your code efficient and clean.
Functions shouldn't be taking many arguments. The ideal number is literally zero here. Then comes monadic, dyadic and triadic should be avoided as much as possible.
Flag arguments, that is passing a boolean to a function complicates the function and they do more than one thing. One for being true and one for being false.
Should have no side effects, and shouldn't do hidden things. This would be a case where a function seems to do one thing and the reader may not notice that it is indeed doing more than one thing.
To avoid confusion, functions should either do something or answer something, but not both. They may modify something or return some information, but not both.
That's it for today.
My opinion
I believe these are some really good tips and tricks. I agree we encounter lots of places where we have to violate these practices. But do we really? I think this is a way to challenge ourselves, writing functions this way wouldn't be easy. We would also combine it with the concept of meaningful names we studied earlier. We have to be descriptive with our functions' names. This would surely take time but it would fruit especially when creating projects and working in collaboration.
I will now see you on Day 6, discussing Chapter 3, 'Saying Yes' from 'The Clean Coder'. Till then happy clean coding!