A Few Thoughts on Clean Code


Having nothing better to write about than the craft that I love.  Today I will write a little bit about clean code.  Seems that most new developers are unaware of the concept of clean code and I don't just mean the book by Uncle Bob.

I mean the whole idea that code needs to be readable.  Code needs to be elegant.  Code needs to be, as my college professor used to say "sexy".  You should be able to look at code and simply admire it. When you look at clean beautiful code it should make you feel smarter because you understand it. And you understand because it is beautiful.  It is elegant.  The code does what it's supposed to do.  It reads like a good prose.

Good code is not tricky.  Good clean code is not for the few uber smart people.  It is for nearly any one to understand, sometimes even non-programmers.

If on the other hand you look at code and say any of the following phrases this is not clean code:

"Oh sh_t!"
"What the ___ where they thinking?!!!"
"It's going to be a long day!"
"Maybe I should change careers!"
"If I quit soon I won't have to deal with this mess any longer!"

One of the problems is that colleges don't teach very much about clean code. Most colleges are only concerned with code that produces the correct output in a best case scenario.  In the real world programs run into edge cases that produce bugs.  Applications need enhancements.  In the real world your code will be read more after creation than during creation.  That is why code must be readable and maintainable.  Everyone can't be super intelligent but everyone can be a great programmer if we simply write better code.

Having read tons of bad code and then reading Uncle Bob's book Clean Code.  I have to re-iterate some of his points about clean code.

Make Names Pronounceable

Names should be pronounceable.  None of this  SrForDdLinks method name. Instead SearchForDeadLinks.  If you can't use the name in a sentence than you should consider renaming the variable or method.

Do Not Use Abbreviations

Don't abbreviate a name unless the abbreviation is widely accepted.  It doesn't matter if your method is short and the name is obvious.  Programs grow over time. Code changes and that x or c variable will lose it's meaning.  Tmp could mean temporary or temperature.  Use the whole word.  Our modern languages have big limits on names. We are not writing assembly anymore where every character counts.

A Smell That Your Method Does Too Much

Shorten the name. If the name is too long perhaps you are doing to much with that method.  SearchForDeadLinksAndDeleteThem tells exactly what it does but it might be doing too much. Perhaps you should separate the search from the delete and name the parent DeleteDeadLinks.

Use "this" in Java

Use "this" for class members. Ok I think C# developers will balk at this but if you are developing in Java and you have no way to distinguish between the class variable named "firstname" and the local variable named "firstName" you should use this (e.g. this.firstName = firstName).  In Java you should use this when accessing any class variables.  Java does not use underscore for class (Java idiom anyway) level scope variables (e.g. _firstName) like C# does so there is no easy way to distinguish local scope from class scope.

Methods Should Be Short

But perhaps if you made your methods shorter this would even be easier.  If your methods are longer than 20 lines or 15-20 lines they are way too long (including blank lines and comments). You should break them down into short subroutines/methods.  It's ok to have helper methods.

Methods, like classes, should do one primary thing and do it well.  Some methods compile a set of other methods for one primary action and that is ok.

Use the Same Level of Abstraction

If your method has method calls in in perhaps all or most of the actions of its body should be other method calls.

For example do this

public PrintReport()
{
        Data data = FetchData();
        Clean(data);
        Print(data);
}

Instead of

public PrintReport()
{
       //fetch data
        Data data = null;

        Repository repository = new InvoiceRepository();


        data = repository.FetchData();


        //clean data

        if(data.IsNotEmpty()){

                 foreach( Record record in data.getRows())

                 {
                               CleanRecord(record);
                  }
         }

        Print(data);

}

In the second example we are using two different levels of abstraction.  The fetch and clean are very fine grained and the Print is very coarse grained.  Keep the granularity uniform for readability.

Use Abstractions for Any External Access

If you're class requires testing and it requires external access, use abstractions such as interfaces or abstract classes instead. If you are using Java or C# use interfaces so that you can use dependency injection (interfaces are preferred over abstract classes).  Your classes need to be testable.  For example if your class requires unit tests which most classes do, all your database access, file access and writing to the console should be neatly hidden behind abstractions such as interfaces.  That is so that you can use dependency injection.  This makes your class testable and available to mocking.

Make Your Classes Testable

Any classes that have considerable logic like data structures (e.g. sorters, trees, finders, etc) need to be testable.  I'm not the biggest advocate of TDD but you should write unit tests for your classes. How else are you going to test for all the necessary cases, (common, best case and edge cases).  Running the application is not an acceptable way of testing your classes.  This will ensure not only that your code works but also that when you make a future change it continues to work.

Comment Your Public API

Any public methods that your classes have should be commented.  You should list at a minimum the intent of the class and the assumptions that you are making as well as parameter requirements for valid data.  I am not a subscriber to the 0 comment ideology. I can't tell you how much time other programmers' comments have saved me by helping me understand their intent.

Summary

Although I wrote this off the top of my head. Most of these ideas are not my own. Instead, they come from an easy and fun to read book called Clean Code by Robert C. Martin AKA "Uncle Bob".  Go out and get that book. It is worth every penny.

Please subscribe below by email so that you can get the latest updates to this blog.





Comments

Anonymous said…
> Java does not use underscore for class level scope variables (e.g. _firstName) like C# does so there is no easy way to distinguish local scope from class scope.

Just to be clear. "Java does not use" is not "Java" it's standard practice. And if your code base already uses underscore, you should continue using it. Consistency is key.

Likewise, it's not a C# thing. Most C# developers don't use underscore. Especially because they often assign to auto properties.

public SomeCtor(string someVariable)
{
SomeVariable = someVariable;
}|
Fernando Zamora said…
You are right. It's an idiom practice of Java. Once upon a time it was standard practice to begin class level variables with underscore in C#. I don't know if that has switched to using only properties always. I haven't been part of the C# environment for quite some time.

I've also noticed that C# has introduced some new features to properties in C# 6.0 such as not requiring the set to be set explicitly to private and initializing properties.

The idea was that in Java you should use this in front of your class level variables since another part of the idiom is to name class level variables the same way as you name local variables.

Perhaps instead of mentioning this thought I should have just pointed out to follow the idiom of the language that you are working in, since this is Java specific.

Thanks for the correction.

Popular posts from this blog

Simple Example of Using Pipes with C#

Putting Files on the Rackspace File Cloud

Why I Hate Regular Expressions