I completely missed this post from Martin Fowler that apparently caused quite a stir in the development community. But that is to be expected - for every person out there that criticizes language X there will be dozens to defend it.
In this case, Martin admits how he likes the fact that with some of the Ruby classes, most if not all of the methods one could frequently need are included. This is contrasted to Java where most of the classes have very minimal interface. The classic example is where Ruby gives you method last for the Array class Java requires you to use something like get(list.length – 1).
Java is not the only OO language whose library follows this kind of approach – most of the highly regarded C++ libraries will look the same as will many C# libraries too. I must confess that I’ve been a subscriber to this philosophy too, but the blog post and the comments that followed made me think.
From whose point of view is the minimalistic interface better than the rich one? Class’ designer or the consumer? Who benefits more if the class has richer interface? To me, the answer is obvious – unless there’s a lot of ambiguity whether method A is better for the purpose than method B (in other words, there is no unnecessary functional overlap, just more convenience methods), the richer interface is better for the consumer but harder for the implementer. My approach would be – implement the convenience methods as long as they add value, that is they are really frequently used like the last method above.
Actually, if you have read (and if you haven’t, I definitely recommend you to buy it) Framework Design Guidelines… from Brad Abrams and Krysztof Cwalina you will notice something really interesting – even though the default “rule” for the C# classes is generally to have relatively thin interfaces, the class designers are encouraged to add extra convenience methods so that the most frequent case is supported by less code from the consumer. This is great practical advice even if it looks like the wrong thing to do as it adds more methods to the classes that would work perfectly fine without them. It is also roughly in favor of Ruby’s approach of having extra convenience functions.
Another interesting perspective is Herb Sutter’s chapter on std::string refactoring in his Exceptional C++ Style… book. He argues that std::string has too many members and that most of these can be pulled out. He then successfully refactors the class into a version with a lot less methods, and keeps the functionality. At first, this might look like a point against Ruby’s approach, until you realize that the functionality is kept only by externalizing the methods into free functions. If anything, I would argue that C++ std::string does not have enough methods, externalized or not, but that’s just me rambling.
I don’t think there’s anything wrong with having convenience methods in your classes, that is methods that can be expressed in the terms of other methods of your class. You just have to be careful not to go overboard and implement any conceivable combination. If you follow the reasoning that Abrams and Cwalina present in their book you can’t go wrong.
We are developing for humans too, not just for the computer/compiler.
Be the first to rate this post
- Currently 0/5 Stars.
- 1
- 2
- 3
- 4
- 5