Michael HönnigMichael Hönnig

"Java by Comparison" leads the reader through 70 examples into software-craftship. Each example compares a snipped of typical "unclean" code with a "clean" replacement, including a short discussion about the reasoning.

What it is about?

This book is a great practical guide for Java developers comprising many aspects from the classical books "Clean Code" [1], "Refactoring" [2] and "Effective Java" [3]. With a length of only about 200 pages it is short enough, not to give any excuse for not having read it as a Java developer. The examples follow a didactically well done learning curve, and the explanations are written in an easy language [4]. The book ends with a chapter about general practices for contemporary software development like static code analysis, build automation and continuous integration.

Who is it for?

I strongly recommend the book for:

  • Everybody, who is learning Java programming and wants to learn it the professional way,

  • junior Java programmers who want to take their next step and become a software craftsperson,

  • senior Java developers as a guide for code reviews and to lead junior Java developers,

  • Java instructors as a foundation for a great curriculum.

Can I recommend it?

Yes! To begin with, in general I agree with all the presented rules. Whenever there are multiple opinions out in the field or exceptions depending on the context, such is also discussed by the authors. I wished these topics were part of college curricula; unfortunately, at least in Germany, this is usually not the case. Great to learn about this extraordinary exception.

Even for me, with >30 years of programming- and over 20 years of Java-experience, there were still plenty new details to learn.

Highlights

One special highlight for me was the chapter "Let Your Data Flow". Here the authors offer great rules for using the Java 8 functional programming features Lambdas and great rules about the use cases for Java 8 Optional.

I also liked a lot that ADRs (architecture decision records) were mentioned: ADRs are schema for recording decisions about software architecture and their reasoning. I also like using this format for design decisions right in the code, as depicted in the chapter "Document Implementation Decisions".

Excursion: Exception handling in Java Streams

One example was keeping me busy for a while was "Avoid Exceptions in Streams". I had not realized before how ugly Java streams can become if exceptions have to be handled and resources be closed as in Java’s "try with resources". The authors show how such can be handled in a half-way decent way. If Java had an Error Handling Monad (compare [5]), it could look somehow like this:

class LogBooks {

    static List<LogBook> getAll() throws IOException {

        return Try.with(Files.walk(Paths.get("/var/log")))
                .filter(Files::isRegularFile)
                .filter(LogBook::isLogbook)
                .flatMap(path -> Try.of(new LogBook(path)))
                .onException( IOException.class, (exception, path) -> Try.empty())
                .collect(Collectors.toList());
    }
}

Unfortunately, there is no such standard API for Try/catch in standard Java-Streams, just in libraries like VAVR [6].

What could be improved or is missing?

In general the code formatting was fine, other than stated in on books review on Amazon [7]. But yet, on my eBook readers (Android Kindle app on Samsung Galaxy Note 12 tablet and Kindle Oasis reader) the lines were sometimes too long. Therefore, such lines continued at the beginning of the next line which makes some code snippets hard to read. Explicit line breaks would have helped.

Does the book contain a complete list of rules for clean code? Of course, it does not, it cannot, and I was not expecting such, there are simply too many of such (compare [8]) Yet, I was missing a few principles which I consider very important:

  • a chapter about access rights restriction (private/protected/package/public), encapsulation, coherence and false abstractions,

  • the SOLID principles: Single responsibility, Open/closed, Liskov substitution, Interface segregation, Dependency inversion

  • and even though SLA (level of abstraction) is mentioned in a few examples, I think it deserves a chapter of its own.

I also suggest applying the stated rules in later chapters, e.g. using final more often. Too bad it’s not the default in Java anyway.

Maybe these are some ideas for a 2nd edition?

Inspiration

While reading the book, I was wondering how the rules apply to other programming languages, e.g. Kotlin or TypeScript. As both type systems are more advanced, some rules simply become irrelevant, but for sure, other rules could come up. Especially in purely functional programming languages a set of such rules would be quite different.

Summary

In total, this book is a must-read for every Java developer to go beyond the junior status, and a great reference for those who have already advanced. With a length of only about 200 pages, there is also no excuse for not having read it.


Disclaimer: I got a free copy for review.

References

[1] Clean Code: A Handbook of Agile Software Craftsmanship, 1st Edition, Robert C. Martin, 2008, Prentice Hall
[2] Refactoring: Improving the Design of Existing Code, 2nd Edition, Martin Fowler, 2018, Addison-Wesley Professional
[3] Effective Java, Third Edition, Joshua Bloch, 2017-12-27, Addison-Wesley Professional
[4] http://www.hemingwayapp.com/
[5] https://de.slideshare.net/mariofusco/monadic-java/39
[6] http://www.vavr.io/
[7] https://www.amazon.de/gp/customer-reviews/R1CB66452UHK9Y/ref=cm_cr_arp_d_rvw_ttl?ie=UTF8&ASIN=1680502875
[8] http://principles-wiki.net/