'Writing Clean Code' - A Step Towards Being A Better Developer
https://www.genymotion.com/blog/the-art-of-clean-code/

'Writing Clean Code' - A Step Towards Being A Better Developer

Being a developer, whether we are starting our carrier or in the industry for years, we always try to enhance our skills. We try to learn new tools, languages and technologies to add in our skill set. Besides technology stacks we know and how much we are proficient, the other thing that really matters for a better developer is, how we write our codes. Everything we know, the problem and solutions, are expressed in terms of the code that we write. The code we write really matter because we need to continuously add or modify the feature and debug it which needs clean and understandable code. Writing easily readable, understandable and maintainable program requires some guidance, experience and enthusiasm. if we want to be better then, we need to look for ways to improve our writing skills. Writing good program is a continuous process. We may have heard of self-descriptive or self-documented code which leads towards writing better program. So, how can we write good program? The answer is to follow the guidelines of 'Clean Code'.

The process of writing good program which is easily readable, understandable and facilitates ease in maintenance is what we call writing "Clean Code". This article includes some of the areas which would be helpful for writing good code as mentioned by Robert C. Martin, also known as Uncle Bob, in his book "Clean Code: : A Handbook of Agile Software Craftsmanship". Writing clean code means considering different dimensions of the program such as naming conventions, comments, error handling, functions and objects and data structures. Things that need to consider on these dimensions that guide us to write better code are as follows:

Meaningful Names: A good name provides lots of information and adds clarity of the program. Class, variable and functions are few to mention where developers have to choose meaningful names to reveal the intended purpose of code. Considering the following points helps to make meaningful names:

  • Use Intention Revealing Names: Giving names to classes, member variables, functions and local variables that revels their usage improves increase in readability, understandability and maintainability.
  • Make Meaningful Distinctions and Avoid Disinformation: Developers have to write often similar objects within a same scope or a same type of variables. In such a situation, choosing a good name is important to provide clear distinction about them. For example: instead of using obj1 and obj2, proper naming is preferred that describes their usage within the scope.
  • Use Pronounceable Names: How do you declare variables of any kind? It can be of Object, Primitive types etc. Are you able to remember the name of classes that you defined in your program? In a small program or project, it is easy but as the program goes large, it is hard to remember all the classes, variables and functions we define but using pronounceable names helps to increase readability, understandability and easy to remember within the scope of their usage scenario.
  • Use Searchable Names: Using searchable names means avoiding generic names such as file1, file2, var1 etc. These terms are hard to search because they can be used anywhere and they do not provide their scope of use which helps in locating them. Searching has become easy with advanced IDE but it still consumes time and relatively produce large results. If we follow the points listed above, then we easily achieve searchable names. Using searchable names helps you to easily locate and your favorite IDE also produce less search results which have higher accuracy and consumes less time.
  • Avoid Encoding: We often write intSum or strName to tell what the type of the variable is. Adding type encoding before the variable name adds no information and reduces its readability.
  • Don't Be Cute: Avoid using fancy names and no one is interested in these stuffs.

Comments: Comments in code plays vital role in understanding them. We are often taught to place comment on programs and write comment for each statement. But, the question is, does the comment is necessary everywhere? the answer is no. This section gives some idea bout writing comments.

  • Legal comments: Any legal concerns such as copyright then add it.
  • Informative comment: If there are any information that you think it is definitely valuable for others then write it. For example: the algorithm being implemented.
  • Explanation of Intent and Clarification: There are some cases when we do certain things that should not be done in that way but the use case requires it. In such case placing comment to explain the intent is good. This will help others to understand why certain things are done in such a way.
  • Warning of Consequences: We write functions that does certain things. There are cases where any interfere to the code or usage in any other scenarios than specified may introduce abnormal behavior, in such case, placing comments that describe the consequences is helpful.

Functions: We write functions that have their responsibilities and together they solve certain problems. For functions, questions such as, how long does it should be ? Is it appropriate to use a single function to provide different functionalities? are very crucial to all developers. Very long detail or many responsibilities for a single function increase complexity and hard to debug and maintain. Therefore, a function should have following properties:

  • Relatively Small: A function should be as small as possible which facilitates ease in debugging, understanding and modification. Some defines function in terms of number of lines and some consider a function detail should be completely visible within a screen. It depends on how much a developer wants. Therefore, a function should be relatively small as possible so that other can easily read, debug and modify.
  • Do One Thing and No Side Effects: If we want our function to be more maintainable and easily understandable then it should be driven by single responsibility which means a function should perform only one thing. Single responsibility also means reducing side effects. If a function does the intended purpose as well as other, then it is not good. Such function can show side effects at any time. For example: for a e-commerce application, using login function to authenticate and initialize shopping cart is bad idea. It can introduce unwanted behavior at any time. It is better to use two functions for authentication and initialization of shopping cart. Therefore, a function should be responsible for only one thing.
  • One Level of Abstraction: A function revels its usage by its name and hides all the details. A function should hide the details it is responsible for which means it should provide only a level of abstraction. In our previous e-commerce example, the login functions provides two level of abstraction, one for authentication and another for initialization of shopping cart.

Error Handling: No software is 100% error free, therefore, error handling is very crucial part in developing applications. We may know or not when and where error can occur in development time but we need to be prepared for errors while developing applications. Error should be handled properly and with care otherwise it can mess a lot. For better error handling and to be on safe side, the following guidelines are helpful:

  • Prefer Exceptions Instead of Error Code: Instead of returning error code such as 0, -1, ERR for error conditions, it is better to use default or custom exceptions. Since exceptions have name, it is more appropriate and helpful in understanding error being occurred. For example, if we encounter file not found error and we return 0 instead of FileNotFoundException. In such case the return code is more verbose and difficult to understand. In such case, if we use Exception then it more understandable and easy to identify the type of error being occurred.
  • Provide Context with Exception: Exceptions should be handled with care. It provides the flexibility as well as increase complexity. Therefore, whenever an exception occurs, it is better to provide context for it. Exception provide lots of information for debugging and providing the context makes it more meaningful. For example, we we are querying a record form a table in a database and we need to throw an exception on record not found then in such case throwing only exception does not provide any meaningful exception being occurred. If we convey ' Record not found' message with the Exception then it is more meaningful. It is also necessary because we can use same type of exceptions in many cases. Making such Exception distinguishable from one another requires context for each occurrence.
  • Do Not Return and Pass NULL Values: Passing and returning NULL values causes a lot of problem. It is also uncertain when it occurs. Any function that accepts and return NULL values are in abnormal state. To prevent any uncertainty, always validate the parameters before calling a function and always return value if it does. If a value does not exist to return then throw an exception with context but do not return NULL.

I hope the above guidelines will help to write better code. Since, it is a continuous process, we need to consider these guidelines in a daily basis to improve what we write and how we write. If you want to have more and clear idea about writing clean code then, read "Clean Code: : A Handbook of Agile Software Craftsmanship" written by Uncle Bob.




Suraj R. Shrestha

Engineering Manager/Certified ScrumMaster? (CSM?)/ Senior Java Developer

8 年

Nice article Sushile.

回复
Lalit Thapa

Software Engineer at Shiftcare

8 年

Sahi ho ale sir

回复

要查看或添加评论,请登录

Sushil Ale的更多文章

社区洞察

其他会员也浏览了