Random Ideas about Code Style
Some of the sentences of this article are ironic. Others are to be taken serious. It is up to the reader to separate them. Start with these sentences.
How long should a method be in Java?
This is a question I ask many times during interviews. There is no one best answer. There are programming styles and different styles are just different and many can be ok. I absolutely accept somebody saying that a method should be as short as possible, but I can also accept 20 to 30 lines methods. Above 30 lines I would be a bit reluctant.
“When I wrote this code only God and I understood it. Now only God does.”
Quote from unknown programmer. Last quarter of the XX. century.
The most important thing is that the code is readable. When you write the code you understand it. At least you think you understand what you wanted to code. What you actually coded may be a different story. And here comes the importance of readability as opposed to writeablity.
When you refactor a code containing some long method and you split up the method into many small methods you actually create a tree structure from a linear code. Instead of having one line after the other you create small methods and move the actual commands into those. After that the small methods are invoked from a higher level. Why does it make the code more readable?
First of all, because each method will have a name. That is what methods have and in Java we love camel cased talking names.
private void pureFactoryServiceImplementationIncomnigDtoInvoker(IncomingDto incomingDto){ incomingDto.invoke(); }
But why is it any better than inlining the code and using comments?
// pure factory service implementation incoming dto invoker incomingDto.invoke();
Probably that is because you have to type pureFactoryServiceImplementationIncomnigDtoInvoker
twice? I know you will not type it twice. You will copy paste it or use some IDE auto-complete feature and for that reason the type replacing ‘Incoming’ to ‘Incomnig’ does not really matter.
When you split up the code into small methods the names are a form of comment.
Very much like what we do in unit tests using JUnit 4.0 or later. Old versions had to start the test methods with the literal test...
but that was not a good idea. It was discovered long time ago. (I just wonder when Go will get there.) These days Groovy (and especially spock) lets us use whole sentences with spaces and new lines as method names in unit tests. But those method names fortunately should not be typed twice. They are listed and invoked by Junit via reflection and thus they really are what they really are: documentation.
So then the question still is: Why is tree structure better than linear?
Probably that is how our brains work. We look at a method and see that there are two-three method calls in that. There can be a simple branch or loop structure in it, perhaps one nested to the other but not much deeper than that. It is simple and if method names are selected well (I mean really in a good, meaningful and talking way), they are easy to understand, easy to read.
The we can, using the navigational aid of the IDE go to the methods and we can concentrate on the limited context of the method we are looking at. There is a rough rule:
You should be able to understand what a method does in 15 seconds.
If you stare at the method longer and you still have no idea what the method does it means it is too complex. Some people are better apprehending the structure of the code, others are challanged in that. I am in the latter group, so when I review code I many times prefer smaller and simpler methods. I refuse the code to be merged or I refactor it myself depending on the role, the actual task I perform. Juniors I work with think that I am strict and picky. The truth is I am slow. The complexity of the code should be compatible with the weakest chain: any one of the team (including imaginable future maintainers of the next coming 20 years till the code is finally deleted from production) should understand and maintain the code easily.
Many times looking at git history I see refactoring ping-pong. For example the method
Result getFrom(SomeInput someInput){ Result result = null; if( someInput != null ){ result = someInput.get(); } return result; }
is refactored to
Result getFrom(SomeInput someInput){ final Result result; if( someInput == null ){ result = null; }else{ result = someInput.get(); } return result; }
and later the other way around.
One is shorter, while the other one is more declarative. Is the repetitive refactoring back and forth a problem? Most probably is, but not for sure. If it happens only a few times and by different people then this is not something to worry about too much. When the code gets refactored the developer feels the code more attached to him/herself. A more “it is my code” feeling, which is important. Even though a good developer is not afraid to touch and modify any code. (what could happen? test fail? so what? test? what test?) Note that not all developers are good developers. But what is a good developer after all? It is relative. There are better developers and there are not so good. If you see only good developers who are better than you, then probably you are lucky. Or not.
Reference: | Random Ideas about Code Style from our JCG partner Peter Verhas at the Java Deep blog. |
About the ping-pong…
I’m not sure if I see any difference. Both are mostly the same from clean code point of view.
Anyway there is third option that is slightly different :
Result getFrom(SomeInput someInput){
if( someInput == null ){
return null;
}
return someInput.get();
}
For methods with simple logic I personally prefer this syntax:
Result getFrom (SomeInput someInput) {
return null == someInput ? null : someInput.get();
}
I recommend that you read the following article before you get surprises with the ternary operator:
https://javax0.wordpress.com/2013/09/18/something-you-did-not-know-about-the-ternary-operator/