Clean Code – Functions – Revisited
A couple of years back I wrote an article exploring a way to apply Robert C. Martins guidelines on how to create clean functions, taken from his book Clean Code. This created quite a stir on DZone where I also published it.
A comment from Steven Jeuris about a week ago on my blog made me want to revisit the subject again.
Since I wrote the original article I have leaned a lot about creating clean functions that does one thing. And as I replied in to his comment I would not design the code in the original article the same way now.
The key to applying the guidelines in the book is pragmatism. There are a number of benefits from working as is suggested there. I will cover some of them below. But it cannot be followed religiously. It is after all software we are creating, not religion.
Steven Jeuris writes, in his blog on the subject, that a perfectly good way to make code in a function readable is to create blocks with comments. This to me is an anti pattern. There are few reasons to ever create blocks in a function, if they are required it generally indicates that the function is to long. Comments are almost always a bad idea. If a comment is required the block should be put within a function bearing a name that explains what the block does.
Steven Jeuris further writes that new small functions litters the name space of the class. I can see where he is coming from but again I have to disagree. If the name space of a class is littered by explanatory function names then it sounds like the class is to big and needs to be refactored. To me it sounds very much like it does more then one thing.
There is also an interesting side effect to creating smaller more atomic functions that does one thing. It is easier to find commonalities between the other, higher level, functions within the same class, or even related classes. This actually makes it easier to keep the code DRY (Don't Repeat Yourself).
Another very important factor to keep in mind when working like this is what patterns the rest of the team are used to. The size of functions and the way to work with them are not a one size fits all. If a team is used to procedural code the step to extract till you drop style functions will be really confusing. If, on the other hand, the team is used to atomic, do one thing only, functions it is hell to work with larger functions littered with comments and artificial blocks.
In any case, I know that if I would do the same exercise to day as I did when writing my original article on the subject it would look different, and the original definitely takes a good thing way to far.