DEV Community

Cover image for Clean Code
Taslim Arif
Taslim Arif

Posted on • Updated on

Clean Code

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

– Martin Fowler

Writing clean, understandable, and maintainable code is a skill that is crucial for every developer to master.


When I say clean code I mean:

  • Proper variable name, function name, class name, proper indentation, proper spacing, proper comment, and proper/unique code style throughout the team.
  • Minimal number of lines of code, classes, functions, etc. Less code means less headache, fewer bugs, and less maintenance cost.
  • No duplication of code. Duplication in your software shows bad software and lack of knowledge.
  • It might seem contradictory to my previous point but too much abstraction is also bad. If your abstraction forces you to add more conditions and extra parameters in your method every time a new feature is introduced, it is a bad/wrong abstraction and you should follow the below things:
    • Try to find a way so that every time you introduce a new feature, your abstraction should not be affected.
    • Go back to duplication. You heard it right. Duplication is always better than wrong abstraction.

Well, I don't see this as a failure of abstraction. It's caused by some specific other failures.

   a. Failure of people to understand data modeling, and the 
      difference between interface and implementation. "A new 
      requirement appears for which the current abstraction 
      is almost perfect. Just because the code is the same 
      doesn't mean it should use the same abstraction. The 
      data model is wrong, not the abstraction.

   b. Failure of people to think of the entire system, when 
      making a change. The rookie mistake is to think that 
      adding one more conditional is always harmless, but, at 
      some point, you've got 3 tons of straw on that poor 
      camel's back. Adding just one more case may have been 
      the correct fix last week, but not this week.
Enter fullscreen mode Exit fullscreen mode
  • No magic numbers (A magic number is direct usage of a number in the code). Magic numbers are bad, they are not readable, they are hard to maintain and they are not reusable.
  • Minimum/No hard coding. It is bad, not reusable, not testable, and not maintainable.
  • Code should pass 100% of test cases(even 99% shows that you are screwed).
  • Code is easy and cheap to maintain.
  • Mature programmers know that the idea that everything is an object is a myth. Sometimes you really want simple data structures with procedures for your task. So you have to carefully think what to implement also thinking about the future perspective that what will be easy to update.

Always write concise documentation of your code( classes, functions, properties, etc.)

Documentation


Tips to write clean code

  • Variable, function, or class names should be descriptive. If it requires a comment to describe what the name does, it's a bad naming convention.
let s; // number of seconds ---> Bad naming convention

Good naming convention:
let numberOfSeconds, customerName, employeeName, mailMessage, mailFolder
Enter fullscreen mode Exit fullscreen mode
  • Do not include any redundant information/ noise words in naming. Some of noise words:
    • Data
    • Object
    • Info
    • Information
    • Variable
    • String
Bad naming convention:

userInfo, userData, userVariable, userObject, accountInformation, employeeString etc.

Good naming convention:
user, employee, account etc. 
Enter fullscreen mode Exit fullscreen mode
  • Be consistent while naming variables of similar tasks. For example, while naming any variable which stores fetched data from an API call or Database use only one of these: get, retrieve, fetch. Don't use more than one as they do the same task.
 Say you decide to follow get convention:
getUser, getName, getFile, getAccount etc. ==> Good convention
getUser, retrieveAccount, fetchName ===> Bad convention
Enter fullscreen mode Exit fullscreen mode
  • Don't use magic numbers(A magic number is a direct usage of a number in the code)
Bad convention:
   if(age>=18) "eligible for voting"

Good Convention:
   MINIMUM_AGE_FOR_VOTING=18;
   if(age>=MINIMUM_AGE_FOR_VOTING) "eligible for voting"

Enter fullscreen mode Exit fullscreen mode
  • Avoid leaving code inside comments because it makes other developers scary to remove them as they don't know whether it is for comment purposes or left to use later.

  • Always follow the coding style defined by the programming language which you are using. Few conventions in Typescript:

    • Variable name should be in the camel case.
    • Function name should be in the camel case.
    • Class name should be in pascal case.
  • Try to follow the DRY (Don't Repeat Yourself) principle.

  • Function name should be a verb.

  • Class and variable name should be a noun.

  • Prefer to use code formatters such as Prettier for better code arrangement.

  • People often ask me, what should be maximum length of variable, function or class name. Well my answer to them:

    If there's a shorter, but yet descriptive way to name the function, variable or class then your current variable, class or function name is long.

Conclusion

The skill of writing clean code comes from using it again and again in software development. It is the least you should follow while writing a software code.

Discussion (18)

Collapse
peter_brown_cc2f497ac1175 profile image
Peter Brown

The purpose of all of these rules is readability. There is nothing less readable than having a code base with needless needless amounts of functions and needless amounts of abstraction.. This notion that functions should only be 6 lines of code is silly and counter productive. As one of the other commenters mentioned, readability is most important.

Collapse
tastaslim profile image
Taslim Arif Author • Edited on

Minimal number of lines of code, classes, functions etc. Less code means less headache, less bugs and less maintenance cost.
My purpose is to tell people not to write 100s of lines of code in the same function. At the end Readability and uniformity is what matters and same I am trying to convey here.

Collapse
peter_brown_cc2f497ac1175 profile image
Peter Brown

Less code does not mean less headache. Better to be more verbose and readable then too terse.

Collapse
janmpeterka profile image
Jan Peterka (he/him)

I slightly disagree with No duplication of code. It's a good rule on general, but sometimes its better to have duplicate code if it keeps you from bad or premature abstractions. Readability over DRYness.

Collapse
asafshen profile image
Asaf Shen

Well written Jan, to add few helpful quotes on top of this:

"A little copying is better than a little dependency." go-proverbs.github.io/

"duplication is far cheaper than the wrong abstraction." sandimetz.com/blog/2016/1/20/the-w...

it is common to see intermediate level developer writing complex code with high readability/maintainability cost just for the sake of DRYness

Collapse
tastaslim profile image
Taslim Arif Author

Yes Jan that's correct. Too much abstraction is also bad. Especially such abstractions which change every time you introduce new feature. At the end of day, it's you who should be aware of various scenarios while writing any abstraction. I always suggest people to write duplicate code for first and second time, for the third time if same thing arises, we can start refactoring. You can read my blog on Technical Debts and Refactoring.

Collapse
mtrantalainen profile image
Mikko Rantalainen

I'd say leaving code in comments is okay if it's accompanied with a comment to tell when to use the code. For example, you could have correct code in a comment but you have to use some kind of workaround while waiting the library maintainer to fix some bug in dependency. And you cannot code automatic switching because you're not sure which version will contain the fix.

However, in many cases you should prefer having a config variable to activate old or new logic for that part, even if the config were called CONFIG_WORKAROUND_FOO_BUG_53663.

Collapse
tastaslim profile image
Taslim Arif Author • Edited on

But why would you leave a code like that and why do you need to design your software such as you need to comment and uncomment your code for different features. I can understand it is okay for testing but I don't think it is a good approach to follow for production ready code

Collapse
mtrantalainen profile image
Mikko Rantalainen

I was thinking a case where logically you should use some code but due a problem in a library that you're using, you have to use some kind of workaround (with possibly worse runtime performance).

However, until the library maintainer has fixed the problem you cannot be sure if the correct code you are currently thinking is the actual final implementation because it could turn out that the library maintainer cannot fix the current API due backwards compatibility issues and you have to use a newly introduced function to get the fixed behavior for the use case you need. And if you use programming language such as C you cannot keep the "probably soon to be implemented code using currently non-existing API" visible to compiler so you have to hide it from the compiler. Putting the code in comments is one common way to do it.

Of course, you can also keep track of such future changes somewhere else but the actual source code. It really depends on how the whole project is implemented.

Collapse
rconr007 profile image
rconr007 • Edited on

Also proper line breaks, like those use by Prettier on long lines. Avoids having to scroll right and left to read reminder of statements. Having proper structured code goes a long way on readability as well.

Collapse
sp1thas profile image
Panagiotis Simakis

Great post, thanks for sharing. Another good practice might be to adopt an upper limit of characters for the function names. If your function name is to long that indicates that you should probably have to break it down.

Collapse
tastaslim profile image
Taslim Arif Author

@sp1thas thanks. Yes I will update the blog. I need to add more points to it.

Collapse
sarcevicantonio profile image
Antonio Sarcevic

Care to elaborate on the Magic Word thing? I don't get it. Also shouldn't it be >= instead of >?

Collapse
tastaslim profile image
Taslim Arif Author

Improved thanks. Magic number is nothing but using direct number in code:

if(name.length()>12){ ----} // here using 12 directly is bad.

Instead we should use
MAX_NAME_LENGTH=12;
if(name.length()>MAX_NAME_LENGTH) { ------ }

Some comments have been hidden by the post's author - find out more