I recently came across Martin Fowler‘s post about FunctionLength.
In that post he stated something about intention versus implementation. Although it might seem a very trivial thing, the impact on code readability is huge!
For example, if I want to check if a book is written by more than one author, I could to something like this:
Book book = ... if (book.getAuthors().size() > 1) { //do something with that book }
That works perfectly well, but:
- It doesn’t tell me the intention of the code: what did the programmer really wanted to check?
- It reveals implementation details that I don’t want to know at this abstraction level. I don’t care if the solution is implementing a list size check.
How to refactor this? State your intentions explicitly, by moving implementation detail to the correct abstraction level:
... Book book = ... if (hasMoreThanOneAuthor(book)) { //do something with that book } ... private boolean hasMoreThanOneAuthor(Book book) { return book.getAuthors().size() > 1; }
Or even better (but not really relevant for this blog post):
... Book book = ... if (book.hasMoreThanOneAuthor()) { //do something with that book }
This way, you can stop reading at the abstraction level that contains the expression
hasMoreThanOneAuthor
, without your mind being cluttered by implementation details. Maybe I will find a better way of checking a book has more than one author without bothering you with it (although in this particular example that seems highly unlikely).
When reviewing code I have now developed the habit to refactor almost every expression that isn’t trivial into its own method. I found that this really improves code readability.