This year I got very motivated to improve the code in the project I was working on. The classes were long and methods confusing. I wanted to learn how I could adjust the code so it took me and my colleagues less time to understand it. I decided to read a very popular book “Clean code by Robert C. Martin”. In this blog I would like to share 5 things I learned from this book.
1 Semantic highlighting
If you are working with a project that has a lot of big bulky methods, it might be useful to use semantic highlighting. This is a functionality to set a highlighting color to a certain parameter or variable. This will help you to differentiate between variables with similar names. If you are using IntelliJ go to Settings > Editor > Java. Choose desired colors and you will see a preview of the result.
2 Functions
The advice for function bottles down to: ‘Functions should do one thing. They should do it well. They should do it only’. But how can we be sure that they are doing just one thing? A piece of advice clean code provides is to make sure that the statements are all at the same level of abstraction. So how to differentiate between the abstractions? For example getHtml() is a very high level of abstraction and .append(“\n”) is a very low level of abstraction. So be aware not to mix the different levels of abstraction inside a function because this can be confusing. Another thing to be careful with is that a function does not have a side effect. See the following code:
public class UserValidator {
private Cryptographer cryptographer;
public boolean checkPassword(String userName, String password) {
User user = UserGateway.findByName(username);
if (user != User.NULL){
String codedPhrase = user.getPhraseEncodedByPassword();
String phrase = cryptographer.decrypt(codedPhrase, password);
if ("Valid Password".equals(phrase)) {
Session.initialize();
return true;
}
}
return false;
}
}
Martin, R. C. (2009). Clean Code. Prentice Hall. Code snippets have been adjusted.
What is the side effect here? Well it is the Session.initialize call. So this method does more than one thing.
3 Comments
I have witnessed debates between programmers about comments. Some say code should explain itself and comments are not necessary. Others say that code without any comments is not possible. The stand of clean code on this is very clear since it calls the usage of comments failure of programmers. Here is an example of a misleading comment:
//Utility method that returns when this.closed is true. Throws an exception
//if the timeout is reached.
public synchronized void waitForClose(final long timeoutMillis) throws exception {
if(!closed) {
wait(timeoutMillis);
if(!closed)
throw new Exception("MockResponseSender could not be closed");
}
}
Martin, R. C. (2009). Clean Code. Prentice Hall. Code snippets have been adjusted.
This comment is first of all redundant and also misleading because it does not return when but IF. If just by reading the comment a programmer calls the method he will waste a lot of his time if closed is not true.
4 Formatting
So this chapter taught me the importance of formatting in a class. How the blank lines should indicate the start of a new concept between code, for example a blank space between the package declaration and the imports can help programmers to understand code more quickly. Code formatting is a way of communication. The functionality is not the most important thing because there is a big chance it will look different in the next release. Readability of the code however has a greater effect on the project.
If you have a class with lots of methods it is useful to place methods that call each other, vertically close. The one that calls the method, caller, should be above the method that is being called. This improved the natural flow when reading a class. A programmer knows where to find the method he is looking for.
To separate concepts of code we can add a blank space, to indicate relationship we should limit space, for example limit space between a field and a method. For example see difference between image 1 and image 2.
public class ReporterConfig {
/**
* The class name of the reporter listener
*/
private String m_className;
/**
* The properties of the reporter listener
*/
private List<Property> m_properties = new ArrayList<Property>();
Public void addProperty(Property property) {
m_properties.add(property);
}
}
Martin, R. C. (2009). Clean Code. Prentice Hall. Code snippets have been adjusted.
public class ReporterConfig {
private String m_className;
private List<Property> m_properties = new ArrayList<Property>();
Public void addProperty(Property property) {
m_properties.add(property);
}
}
Martin, R. C. (2009). Clean Code. Prentice Hall. Code snippets have been adjusted.
Every developer can have a preference for formatting rules but when working in a team you should come to an agreement. Take some time to agree on indent size, placing of braces, naming classes, variables etc. Use the IDE code formatter to encode the rules so you stick with it.
5 Exceptions
An advice is to use unchecked exceptions. The reason is that checked exceptions come at a price and are not necessary to write robust software. For example you have a method at a low level that changed and now uses a checked exception. The catch is three levels up so now you must declare the exception at each method between them. Because all functions in the path need to know the information of the exception, encapsulation is broken. So when using checked exceptions know they come with this cost. It is for you to decide if it outweighs the benefits. Also think about the context of the exception. The error message should be informative enough to determine the intent of the operation where the exception occurred, because the stack trace won’t tell you this.
These are the 5 things I learned from clean code, but there is much more to learn. I hope my blog inspired you to read the book.