I was reading through the "Refactoring--By Example" chapter of Test-Driven Development in Microsoft .NET today when I ran across a tip that really stuck out at me:
When you see a block of code with a comment attached to it, it is often a good idea to extract that code into a method and make sure that the method's name conveys the meaning specified by the comment.
In the past, I tended to think of methods as a way to reduce duplication in code. If you have two or more sections of code that are very similar, you create a method that encapsulates that similarity, remove those sections, and replace them with calls to the new method.
What the above quotation makes clear is that methods are more than just a way to reduce duplication and promote reuse. A method should also be used to logically group lines of code together, even if the method is only called once.
This is an important realization one must come to on the road to producing more readable and maintainable code.
Don't forget that there are other ways to logically group a chunk of code together, such as using a block in many languages. In Ruby, you can use begin... end as an expression, or you can use some meta-programming sugar such as "let" to create a little scope for some functionality.
ReplyDeletep.s. re-subscribed!
Good point, Reg.
ReplyDeleteP.S. I know I need to work a _lot_ harder before my blog will really be subscription-worthy.
Yes, great realization, methods are executable comments. They're a way to hide the implementation of an idea behind a clear meaningful name *so you don't have to look at the implementation*.
ReplyDeleteGood software contains many one line methods that are never used more than once, and that's totally OK. If each method conveys a single idea about how a process works, it's also much easier to customize a process by sub-classing and overriding individual methods (ideas).
When you extract methods to express individual ideas, reuse happens by accident, you start reusing methods because they're there and already express the idea you need.
It's a good point, and a good practice. But like most everything in software, you need to apply it thoughtfully, or you'll make your code more brittle, and harder to read. If you group the wrong lines together, or provide a poor name, you're working against future coders.
ReplyDeleteIf you need to change the flow of logic, and the wrong lines are grouped behind bad names, you'll need to break those methods down, and maybe recombine their lines into other methods. The bad names make that job that much harder.
In the case of a single-use method it would be better to keep it within the method that uses it, if your language allows that, so that you leak less from the implementation of methods.
ReplyDeleteYes folks, this means that most if not all private methods can disappear.
This is also written in Fowlers "Refactoring - Improving .." book.
ReplyDeleteI have actually started using methods as a form of documentation, and I think it works really well, but at the same time I don't over do it.
This method is very nice the old, bloated codebase I am working with. Often I can refine code that was slightly dissimilar to use the same methods in the end.
Those are two good things: reuse of code, and naming. But neither are unique to object-oriented programming. These are both basic, good modular programming.
ReplyDeleteThe thing that makes object-oriented programming pay off is the message send itself. Sending a message to an object and allowing the object to determine what code to execute is paramount. Now I can parade a thousand objects in front of you, and you can send the same message to each of them, and each can choose to execute whatever they want to execute.
It's not reuse, it's not naming, it's the ability to extend a message send into a thousand different ways that is critical. Some of those ways may not have been even thought up at the time you decided to use that message selector.
Wow. Some great comments here. Thanks, everyone.
ReplyDelete@ramon leon:
"Good software contains many one line methods that are never used more than once, and that's totally OK."
I remember reading a statement very similar to that in "Programming Ruby". The author said that if you end up with a lot of one or two line methods in your Ruby program, then it's a sign of good design on your part. That really made me stop and think. I had heard several times in the past that it's good to limit a method to one "screenful". It was a bit shocking to hear someone advocate keeping your methods to a line or two. I will definitely keep that suggestion in mind from now on as I write my programs.