Mar 28
Simplicity *does* mean simple, readable methods
Following a link from @raganwald I came across an article where Mike Taylor was debating wether the concept of simplicity, as it pertains to the length and complexity of methods isn't subjective. He read a decent chunk of Fowler's Refactoring, found himself disagreeing with the tendency to composable, well named methods, in favor larger methods with the low-level implementation in the method itself, and hoped maybe he was wrong, because the lure of The One True Way is strong. While I am often a subjectivist, as I told my fiance, "Honey, somebody on the internet is wrong - I must inform them immediately."
Basically Mike breaks it down into two approaches: top-down, where the methods are named what they do and abstracted away so you don't see each step of implementation at the top, and bottom-up, where the main method is a little larger and is built up of the implementation itself. He favors bottom-up, and I am a partisan of the other camp, as rubyists often seem to be.I think there is one most important reason to favor the big-picture top-down in this dichotomy. From top-down you can dive down into the implementation and see the details if you chose, but in bottom-up there is no way to get the equivalent top-down view without just reading and understanding the whole program. Basically, advocating the bottom up approach is like making world-maps illegal, because you can get a better feel for navigating your hometown with a city-map.
From this flows the second most important reason, the inability to mentally page out to disk, so to speak, means you have to hold more of the program in your head to understand what is going on. That means as the program grows in size, it gets harder and harder to keep track of it all. And the reason this is really a problem, is when it comes time to introduce new people to the code. By not abstracting things away into bite-sized chunks you've just forced them to learn every piece of everything involved to have a hope of understand things enough to actually get any work done.
A third point: various software engineering theories like: cyclomatic complexity and single-responsibility principle.
I will admit that getting carried away with classitis and class hierarchies, Java style, has some cost, when it comes to following what a program does. There is a little balancing act required there. But, I do think, that decomposing methods is an unequivocal win. I think Rein's tongue-in-cheek talk on Unfactoring is a better visual, code-based proof of the importance of this for maintainability than anything I could whip up here (about 5 minutes in he gets into the examples).
Lastly, who hasn't gone back and looked at their old code and wondered what they were doing? If you want to go back and tweak something, it's painful if you have to refigure out every piece of implementation. This is a case where scanability and readability is a huge win.



Scanability and readability are always a huge win -- that's not in dispute. The issue is how to achieve those goals.
http://gist.github.com/346989
(same url, I added another file to that gist)
def can_checkout_movie?
# account_is_current?
(Date.today - account.last_membership_renewal_date) > vendor.membership_period &&
# available_rental_slots?
movies.currently_checked_out < max_movies_rentable &&
# late_fees_within_limit?
account.late_fees < (account.is_premium? ? vendor.max_late_fees_for_premium_account : vendor.max_late_fees_for_regular_account)
end
and then refactoring to methods the second time you need to write the same code?
My point is how would you know what condition you are checking for if you don't comment it? Doesn't this looks like an excellent case for the "comment the why not how" principle?
commented-to-hell-and-back version. And that's coming from guy who
doesn't like short functions.
Thinking about it, it probably comes from my TAing years teaching C++ to freshmen as their first language.