“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
“I can code.” I always say to myself.
But do others think the same? Is my code good enough for people to understand? Do other people think “Damn I wish I could write such code.?” – that’s the main question I always had in mind.
Definition of Clean Code can vary from person to person. Clean code is subjective and every developer has a personal take on it. In my opinion, I found it to be the simplest definition :
Clean code is a code that is easy to understand and easy to change and has a same meaning for everyone.
In this blog, we will be covering some of the best practices that we should keep in mind for writing a good code. We will be taking reference from Robert C. Martin’s Book: CLEAN CODE. I am keeping this blog generic i.e it won’t be bound to a specific coding language.
Robert C. Martin in his book: Clean Code clearly states the following :
“Nothing can be quite so helpful as a well-placed comment.
Nothing can clutter up a module more than frivolous dogmatic comments.
Nothing can be quite so damaging as an old crufty comment that propagates lies and misinformation.”
TO COMMENT OR NOT TO COMMENT
- “Don’t comment bad code – rewrite it.”
Comments Do Not Make Up for Bad Code! One of the more common motivations for writing comments is bad code. We write a module and we know it is confusing and disorganized. So we say to ourselves, “Ooh, I’d better comment that!”
- Use Only When There seems no Way Out
When you find yourself in a position where you need to write a comment, think it through and see whether there isn’t some way to turn the tables and express yourself in code. If not, go ahead. Who can stop you?
Here are Some Examples of Some Good Comments and Some bad Comments :
EXPLAIN YOURSELF IN CODE
If you need to explain in English what your code does, you have failed to explain with your code. Let’s have a look at an example :
Here, we need to use a comment to explain what the if condition does.
How about we replace it with a method with a useful name :
Smaller and Easy to Understand. Right?
COMMENTING OUT CODE – DON’T DO IT
Coders feel Commented Code is Invisible.
No, It is Not.
Others who see that commented-out code won’t have the courage to delete it. They’ll think it is there for a reason and is too important to delete. So commented-out code gathers like collected salt at the bottom of a not-so-well-stirred lemonade.
We’ve had good source code control systems for a very long time now. Those systems will remember the code for us.
Code formatting is important. It is too important to ignore and it is too important to treat religiously. Code formatting is about communication, and communication is the professional developer’s first order of business.
Using IntelliJ, we mostly consider ctrl + shift + Alt + L as our formatting spell. But have you ever wondered what’s the best way to format the code?
In this part, we will have a quick look on that only.
- A messy code is hard to read.
- When people look under the hood, we want them to be impressed with the neatness, consistency, and attention to detail that they perceive.
- You should take care that your code is nicely formatted. Code formatting is important. Code formatting is about communication, and communication is the professional developer’s first order of business.
- Topmost parts of the source file should provide the high-level concepts or abstractions and details should increase as we move downward.
- Dependent Functions: If one function calls another, they should be vertically close, and the caller should be above the callee, if at all possible. This gives the program a natural flow.
- Smaller classes are easier to understand. Try to write a class with around 200-500 lines.
- Vertical Openness: Methods should be separated by blank lines, also lines of code that differ in functionality should be separated by blank lines.
- Programmers clearly prefer short lines. Keep your lines short! Set a limit of characters per line of code.
- A good character limit on a line is 120-150. You should never have to scroll to the right.
- Use spaces between operators, parameters, and commas.
- Indentation -It is a good practice to indent the lines of source code according to their hierarchy levels so that it would be easy to visualize the scopes.
We all must have heard that in our code The Classes Should Be Small !!
But the question that often comes to our mind is HOW SMALL????????
- With functions, we can measure size by counting physical lines. With classes, we use a different measure. We count responsibilities. We will be discussing the responsibilities later in The Single Responsibility Principle.
- The class name should represent your responsibility. If you cannot derive a good class name, it’s probably too large / too broad a scope.
CLASS DESIGN PRINCIPLES
In this part, I will list down 5 most recommended design principles, you should keep in mind while writing your classes. These design principles are called SOLID, in short. They also form the best practices to be followed for designing your application classes.
The Single Responsibility Principle
The Single Responsibility Principle states that a class or module should have one, and only one reason to change.
This principle gives us both a definition of responsibility and guidelines for class size.
Let’s have a look at an example: In this screenshot, you can see that the class SuperDashboard has 2 reasons to change i.e version info and GUI components :
So this class does not follow the Single Responsibility Principle. But the class Version has only one reason to change i.e The version info. Thus it follows the principle. You can have a look at the class below :
Open Closed Principle
This principle simply states that the classes should be open for extension but closed for modification.
Interface specifications can be reused through inheritance but implementation need not be. The existing interface is closed to modifications and new implementations must, at a minimum, implement that interface.
We will receive benefits as flexibility and prevent appearing new bugs.
Liskov’s Substitution Principle
This principle is a variation of previously discussed open-closed principle. It says:
“Derived types must be completely substitutable for their base types”
The idea here is that objects should be replaceable by instances of their subtypes and that without affecting the functioning of your system from a client’s point of view.
This principle basically confirms that our abstractions are correct and helps us get a code that is easily reusable and class hierarchies that are very easily understood.
Interface Segregation Principle
Classes that implement interfaces, should not be forced to implement methods they do not use
Robert C. Martin says:
Clients should not be forced to implement interfaces they do not use.
In other words, it is better to have many smaller interfaces, than fewer, fatter interfaces.
Dependency Inversion Principle (DIP)
This principle is actually very simply stated:
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend upon details. Details should depend upon abstractions.
The Agile and TDD movements have encouraged many programmers to write automated unit tests, and more are joining their ranks every day.
But in the mad rush to add testing to our discipline, many programmers have missed some of the more subtle, and important, points of writing good tests.
HOW SHOULD I WRITE TEST CASES?
It isn’t hard to write clean tests, but it takes a lot of practice, and that is why so many developers are struggling with it. So we have listed down certain parameters which might help you write clean tests.
Use the F.I.R.S.T rule for testing:
- The test is fast-running.
- The tests are independent of other.
- The test is repeatable in various environments.
- The test is self-validating.
- The test is timely (TDD)
- First Law: Do not write any production code without a failing test first
- Second Law: Write only enough test code as is sufficient enough to fail
- Third Law: Only implement a minimal code that makes the failing test pass.
KEEP YOUR TESTS CLEAN
What makes a clean test?
Readability is perhaps even more important in unit tests than it is in production code.
What makes tests readable?
The same thing that makes all code readable: clarity, simplicity, and density of expression. In a test, you want to say a lot with as few expressions as possible.
“The pattern to keep your code organized”
Build: the first part builds up the test data.
Operate: the second part operates on that test data.
Check: the third part checks that the operation yielded the expected results
Here is an example for reference :
ONE ASSERT PER TEST
Tests come to a single conclusion that is quick and easy to understand.
The main motive behind this is the ability to understand where the code is breaking rather than knowing that the code is breaking.
Using single assert per test cases will let you know which all test cases are failing. But, multiple asserts will only fail at the point where the first assert fails without checking the further asserts. This helps us to have a better idea about the points at which my code is breaking and what the issue is.
To sum up, what we have covered in the blog, let us have a quick look at what all we need to keep in mind while writing code.
- Start with bad code and clean it
- Keeping things small
- Keeping code readable
- Follow all the Standards
- Follow the class principles
- Clean Unit tests are a must
Remember !!!!! You are the one responsible for how presentable your code is !!!!!
In the end, let me just point out the Boy Scout Rule by Robert C. Martin.
Clean Code – Robert C. Martin
You can also have a look at another of our blog on Clean Code: here
Hope This Helps. Stay Tuned for More. 🙂