From: Marnen Laibow-Koser Date: 2009-11-15T11:56:13+09:00 Subject: Implementation inheritance -- was: Re: DRYing a Regex James Edward Gray II wrote: [...] > Now you answer the question you ignored, what about the well-known issue > of inheritance producing tight coupling. :) Here's a link to a good > description of the problem, from a Java point of view: > > http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html Oh, Allen Holub. This is the same guy who thinks that MVC is not object-oriented (see http://c2.com/cgi/wiki?MvcIsNotObjectOriented for discussion and link to original article). Anyway, Holub's argument -- that one should code to interfaces, not classes -- means a lot to programming style in Java, but very little to programming style in Ruby, I think, precisely because Ruby is dynamically typed. You don't have to declare typed variables in Ruby, and you're generally not even interested in the type of an object in Ruby, because Ruby's duck-typing means you don't care. You know all this, of course. But I don't think you appreciate that it basically renders meaningless the "flexibility" part of Holub's thesis. His examples are good in Java, but not in Ruby. Consider the Ruby version of Holub's first "bad" Java example: def f @list = LinkedList.new g(@list) end def g(list) list.add(...) g2(list) end Unlike in Java, g doesn't need to assume anything about its argument except that it won't complain when it receives an :add message. We could change the type of @list completely and g would not break in Ruby, as long as the new object can handle an :add message. Likewise, Holub's first alleged example of the coupling problem is nothing of the kind. The problem with his Stack class isn't that it uses implementation inheritance -- it's that it uses implementation inheritance *inappropriately*, by exposing a public method in the base class that will leave the derived class in an inconsistent state. That's just a plain bug. In this case, composition should have been used instead of inheritance (yes, I wrote that before reading that it was Holub's suggested solution too!). It's like using a hammer to drive a screw -- the fact that it doesn't work very well means that it's the *wrong* tool, not a *generally bad* tool. The Monitorable_stack example is certainly a better example of the fragile base class problem. But I don't think it's fixable with interface inheritance. Apparently, neither does Holub: his supposedly "interface-based" rewrite is actually composition-based (notice the Monitorable_stack.stack member), and would work just as well if no interfaces were involved. I will be charitable and assume that Holub was merely being sloppy here, not deliberately intellectually dishonest. Either way, it does nothing to advance his argument in favor of interfaces. This article is appallingly poorly thought out, and in any case only warns against using typed arguments (hardly possible anyway in Ruby) and using inheritance where composition was actually necessary (a basic OO analysis mistake). It brings little or nothing useful to the present discussion. > > James Edward Gray II Best, -- Marnen Laibow-Koser http://www.marnen.org marnen@marnen.org -- Posted via http://www.ruby-forum.com/.