Clean Code: It Does Really Spark Joy
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.-Martin Fowler
What defines a cool programmer? Some say a cool programmer is a programmer that can create complex logic. Others say that a cool programmer is a programmer that creates CRUD applications in no time. Well for me, a cool programmer is a programmer that can create code that really sparks joy. That means the code that is created not only just functional or optimized, but also code must be readable & understandable by someone who didn’t even barely see the code before. If you want to achieve that, you can follow clean code principles.
Why do I Care About Clean Code?
Imagine you develop an application. After several hours, you managed to develop that basic working application. Then, you decided to open-source it because you want that app to be continuously developed and it’ll be tiresome for you to develop it alone. Let’s just say your code will be look like this.
However, not even anyone cares about your code because your code is just a bunch of clusterfucks.
It works functionally but it doesn’t sustainable as anyone doesn’t know what’s your app is doing so it becomes an abandoned application. What happened if this happens in a company context? There will be greater consequences more than just abandoned applications like loss of bucks, etc. You can check out this interesting real-world case that badly-written code could affect the development process https://www.quora.com/Game-developers-what-do-you-think-of-Yandere-simulator-Is-the-current-progress-in-6-years-understandable-due-to-it-being-developed-by-one-person. Many software projects involve not just a sole programmer, but many programmers and not just you that must understand what’s your code is doing, but others have to. That’s why clean code is important in order to make our software more continuable.
Code is clean if it can be understood easily — by everyone on the team. Clean code can be read and enhanced by a developer other than its original author. With understandability comes readability, changeability, extensibility and maintainability. — Robert C. Martin
Benefits of Clean Code in My Software Engineering Project
In the software engineering project course, we have to develop an e-judicial process system software as a team. So we need to understand each other’s code. So that’s why clean code matters in this software engineering project. By implementing clean code, we reap some of the benefits:
- Ease the collaboration process & add positive vibes
- Less time for code understanding
- Make the code more reusable
A bit of my experience in this software engineering project, in the second sprint I got the task to create a CRU endpoint for “surat dakwaan”. The endpoint must be accessed only by authenticated users so there must be some kind of authenticated router that has authentication middleware that I can use. Fortunately, my friend has already created that one and name the router nicely so I can understand that router is indeed an authenticated router so I can just attach the dakwaan-related endpoints to that router. And now that’s what I called “spark joy”.
Clean Code Principle In Practice
There’s no better explanation than to relate the principles with implementation. I’m not gonna explain all of them in this article since it takes a lot of time so I just put several principles that are most useful and common ones.
One Function Only Serves One Responsibility
By maintaining one responsible for one function, we can reduce the hurdle on debugging process because we make the function more simple. More complexity means more hard time for debugging. You can take a look at this sample golang function that’s used for attribute verification called verifyDakwaan from my project.
As you can see verifyDakwaan responsibility is just to make sure all the attributes are valid (terdakwa, alamat, pekerjaan, etc), no more and no less. The complexity of the attribute verification process is delegated to another function called verifyStringAttribute that checks whether a string attribute is valid or not. By doing this, if there’s some change in the attribute specification, we just modify the verifyStringAttribute. By doing this, the responsibility between is clear cut so we can determine easily which function should be improved or changed later.
Now let’s check a bad example that violates this principle. This snippet is taken from myPPW group assignment.
As you can see,that function is to summarize the order. Well the problem is that function does much more than just summarize the order, but it also processes the attribute, validates the attribute, etc. First, that function is too long to read since it doesn’t delegate other responsibilities. Second it harder to debug, because we don’t really focus on the summarization logic, but also the validation and stuff for that function.
Comment Only If It’s Really Necessary
By clean code principle, we don’t need to put additional comments unless it’s really necessary like TODO some important notes, etc. In reality, the best practice for golang is to put every publicly defined function with one comment. So the best way I think to overcome this problem is just to put the method name on the comment since I think putting the method name on the comment doesn’t really put junk stuff.
You can see that method intuitively returns dakwaan entity with a specified ID from the database. Now compare with another bad example taken from my PPW group assignment.
That clearly violates the principle because if it’s wrong then fix it. Don’t comment on some bad or redundant codes.
Use One Word/Term to Represent One Concept
I think it’s important to use one word consistently to represent one concept. Imagine how confusing it must be if you use let’s say get method that has different naming like “retrieve”, “get”, and “fetch”. You can take a look on this sample dakwaan repository code from my project. Here, I use one word for each concept (Get for “get” concept, Create for “create” concept, Update for “update” concept).
We need to stay consistent especially on naming conventions to avoid confusion. On a project that involves a team, we need to agree between teammates what kind of convention that’s going to be used. For example in our case, we agree to use camelCase for the JSON attribute. So one of our JSON is going to be like this.
Do Code Review
No matter how good we really are writing a clean code, it’s still important to do a code review because we need to make sure that the code is still understandable to others. In the context of our software engineering projet, we do code every time someone want to merge some changes to another branch.
Besides doing code review on merge request, we can also check the code quality by using linter (this should check whether the code is following good practice of a programming language) and sonarqube(this one is more detailed).
Minimize Code Duplication As Possible
I say minimize because I think it’s almost inevitable that there must be duplication in code. What can we do is just minimize the code duplication because with many duplications, the code is becoming less rigid so therefore it’s harder to change. Some tips here, you can change some repeated string by assigning it to constant/variable so when there’s a change in the string, you just change the constant/variable’s content like this example.
Another tip is just to assign some repeatedly used to a function. Here is an example of that tips.
Notice that I created getMockDakwaanEntity() since dakwaan entity creation is repeatedly used by those unit test functions. Therefore I just create it as callable function to reduce code duplication.
As the famous quote says it’s better to safe than sorry. Therefore it’s important to anticipate any error that could be occurred. To do that we need to create error-handling almost in every parts of code. You can check out this example.
Here on CreateDakwaan, we anticipate two kinds of possible errors. First when there are invalid attributes and second is when there’s an error in the entity creation on the database. As you can see the method return two kinds of output, the entity and the error. If the first case happened, it’ll throw an error that’ll say the corresponding attribute is invalid. Meanwhile, when the second case happens, the error from the database will be thrown as an error output.
One Test Function Should Cover Only One Case
This concept is pretty much the same as one function only serves one responsibility concept, but we apply it to our unit test code. One thing that I like about this principle is that I can realize sooner that I could miss some cases that should be tested. You can check the implementation example below.
As you can see those two tests test GetByDakwaanID function. The first covers the case when the corresponding dakwaan is successfully retrieved and the second covers the case when the corresponding dakwaan with the given id is failed to retrieve.
How Clean Code Really Changes My Mindset on Writing Code?
As someone who has disorganized personality traits, I think that mindset really affects me even when I write some codes. I used to think like, “well I don’t care about readability, as long as my code works then why bother about it?”. With this software engineering project that enforces us to create nice & cleaner code, it really transforms my mind, like really. I must think thoroughly before I code like, is my code readable/understandable by others. Is my project structure is understandable by others, etc. It takes a bit more time for getting used to this kind of habit as I used to code recklessly for long enough (for someone who worked with me must be know how reckless I am to put variable names every time I code). Well, it changed my mindset especially when I code casually. I write more readable code than usual unconsciously even myself wondered that the code isn’t made by myself because it looks more understandable. I really hope this mindset could affect also those kinds of traits of mine (read: disorganized) that really bugging me until now.
Clean code ain’t rocket science. It’s a habitual mindset, so you just need to get used to it
I think every programmer should doing a clean code principle because it makes our code more humanly understandable. The code that is written should be like a book. You know the section that explains something so you go through that section and the content is all related to that title. The same goes for code when you want to improve some parts of your code, make sure the code tells you the part that’s needed to change. Tl;dr make your code self-explanatory by doing clean code. Emotionally speaking, clean code really does spark joy because it reduces the hurdle of debugging, eases the collaboration process, and reduces the code understanding process.
That’s all from me about clean code. I hope you enjoy this article and see you in the next article.