Any fool can write code that a computer can understand. Good programmers write code that humans can understand. – Martin Fowler
The intent of this blog post is to make sure that we are writing code which is readable, understandable, maintainable. A readable code helps its maintainer and results in lesser issues and bugs over time.
I have summarised some of the most common things which we can do with Java 8 and above. All these things will ensure that our code is readable and is more understandable.
This blog post compliments the existing guidelines and then apply them on the Java’s functional style of coding. In no way I am introducing anything new. I am just sharing we already know from earlier versions of java and applying them on the functional style of Java programming.
1. Do not create long anonymous methods.
Anonymous methods are good in a way as they allow us to avoid a class where we only need some behaviour. However they have one serious short coming with respect to clean code guidelines and i.e “They do not have a name”.
Method name reflects what a method is doing and thus names helps us in improving the readability of the code. Without a name there is no way to appreciate what a chunk of code is doing without reading each and every line.
Just for this reason please do not create long anonymous methods or you can also follow the below point.
2. Store your functions in a readable variable
This is in continuation with the first point. In case you still need a slightly long anonymous method then store that method in a variable with a readable name. In this way you can still have a name to your anonymous method. This will help us in improving the readability without losing on the benefits of the anonymous methods.
Example:
In the below example we will try to cover the above two tips. You can see that we are doing some filtering on the teachers belonging to our school. However the filter logic which is fairly simple is looking complex just because we do not have a name which could have highlighted the intention of the filter.
school.teachers.stream()
.filter(teacher -> teacher.getClasses().size() > 5 && teacher.getExperience()/12 > 4)
.collect(Collectors.toList());
Lets assign our Lambda to a variable
Predicate<Teacher> filterTeachersByClassCountAndExperience = teacher -> teacher.getClasses().size() > 5 && teacher.getExperience()/12 > 4;
Now we can then use the above variable in our stream which also makes our whole stream more readable.
school.teachers.stream()
.filter(filterTeacherByClassCountAndExperience)
.collect(Collectors.toList());
There is one more benefit of using this predicate. We can now reuse it in case we need the same filtering in some other place.
3. Use method references where ever possible.
If you can use method references in place of lambdas always try to use one. This again helps in code readability.
school.teachers.stream()
.filter(filterTeacherByClassCountAndExperience)
.map(x -> x.getName())
.map(x -> x.getFirstName())
.collect(Collectors.toList());
The above stream processing can be rewritten as below which makes our code more readable
school.teachers.stream()
.filter(filterTeacherByClassCountAndExperience)
.map(Teacher::getName)
.map(Name::getFirstName)
.collect(Collectors.toList());
4. Do not ever create streams on streams.
This should be a no brainer. Streams helps us in working on our data structures in a functional way. However once we are creating a chain of streams and then processing those steam, we have ensured that no human can easily understand what you are doing.
Conclusion
I have summarised a few tips which will help you in writing a clean functional style of code in Java. Follow these whenever you are using Lambdas and streams and this will help the reader of your code to better understand what that code is doing.
Please do let me know in the comments in case you feel that something is not correct or I should cover some more stuff. Happy Coding!