From: Austin Ziegler Date: 2007-10-09T11:32:24+09:00 Subject: Re: The Case for Multiple-Inheritance On 10/8/07, Martin DeMello wrote: > On 10/8/07, Austin Ziegler wrote: > > Wrong. Look VERY CAREFULLY at your code, Trans. How many of your modules > > are used in more than one place? > > > > If the answer is few, then you're doing it wrong and you're introducing > > negative consequences in terms of maintainability, while not actually > > increasing reuse. Most methods are specific behaviour for a given state. > > Pretending that by extracting that into modules that youre increasing > > reuse is nonsense. Unless you're actually reusing the code, you're not > > increasing reuse. > > Here I have to disagree. This is from some actual code I've written: [snip] Fair enough. I think it's an odd enough case, though. Even then, I'm of the opinion that some of your design could have been different. Specifically, why not something more transparent? monitor = Monitor.new(:linux) class Monitor def self.new(platform, *args, &block) mon = Monitor.alloc mon.initialize(*args, &block) case platform when :windows require 'win_metrics' mon.extend(WindowsMetrics) when :linux require 'lin_metrics' mon.extend(LinuxMetrics) end end end > Now WindowsMetrics and LinuxMetrics are modules that exist solely for > the purpose of being included in Monitor, and you could argue that > instead I could have simply made win_metrics and lin_metrics reopen > the class and add the methods when required. The benefit I've gained > here is that for the cost of an extra layer of indirection and a few > extra lines of code, I've got a huge increase in readability for > someone who looks through my code, since the natural entry points are > win_monitor.rb and lin_monitor.rb. Also, should I ever wish to make a > program that is deployed on multiple platforms and dispatches at > runtime, I can trivially require both metrics files and not have to > worry that they'll stomp on each other by the mere act of requiring > the. I may not be promoting reuse, but I'm definitely increasing > maintainability. Your pseudo-code also suggests that you're not just using WindowsMetrics and LinuxMetrics to provide the entire body of the Monitor class, which is *exactly* what Trans was advocating. With WindowsMetrics and LinuxMetrics, you may not be sharing code/implementation, but you're definitely sharing interface. Your example is probably not much different than: class AbstractMonitor; end class WindowsMonitor < AbstractMonitor; end class LinuxMonitor < AbstractMonitor; end (The latter approach, or even the Monitor.new approach I showed may be better if you ever wanted to support remote monitoring. But that's a different issue entirely and the decision on the architecture shouldn't be based on what you think you might need.) -austin -- Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/ * austin@halostatue.ca * http://www.halostatue.ca/feed/ * austin@zieglers.ca