Rick Denatale wrote: > Cars don't behave like engines, they use the engine internally to > provide their power source. You are right; the word 'behave' vs 'use' is the key. I could not resist letting the 'vroom' reach the Engine without any intervention from Vehicle; and I let expediency trounce principle. Your eloquent point is taken. > vw_bug.engine.vroom violates the 'law' of Demeter, which says that > it's bad style to reach through one object to get at another > So I think that to start the car it should be something like > .. > vw_bug.start > > And the start method would cause the engine to start, producing Vrooom > as a side effect, depending on the particular engine which was > installed by the factory. Here we disagree; not on (what I prefer to call) the "principle of least knowledge", but on the example at hand. Removing the 'vroom' method from the user is a bad application of that principle; customers do not always 'vroom' to start the car, but to assert something (that I hope I don't need to explain). It is enough to watch a city intersection for a few minutes at a traffic light to see that. Removing the 'vroom' is not an option. [In fact, I liked the module Engine, exactly because of that: it removed the need to put knowledge of 'vroom' in the Vehicle! but enough on trying to justify my sin]. I agree that the problem 'vw_bug.engine.vroom' is that it breaks encapsulation. It seems that we are left with having to put a method in Vehicle to 'vroom', just to transmit the command to the engine.. ============ Liam wrote: > require 'forwardable' > .. > class Vehicle > extend Forwardable > def_delegator :@engine, :vroom > attr_accessor :engine > def initialize(engine) > @engine=engine > end > end > > v=Vehicle.new(Engine.new) > v.vroom > v.engine=MustangEngine.new > v.vroom > As far as comparison to Java, this example uses duck typing. As long as > it vrooms, you can use it as an engine for your vehicle. Interesting: this solves the problem of explicitly writing a 'vroom' method in Vehicle just to pass it to the Engine. I am not totally comfortable with the thought of Car 'delegating to' (as opposed to 'having') an Engine, but it is very elegant. ========= Personally, I learnt/conclude this (in view of some vagueness in other comments that seem to say the Composition is not needed): 1) Thufir was right (aside on the details for how to 'vroom'), in seeing the Engine as a Composition problem for Vehicle. There is an instance variable @engine in Vehicle! (shame on me for attempting to remove it :-). 2) we can use 'Delegation' to avoid silly 'bridge methods' in Vehicle, to allow the user reach the Engine, when needed. Thanks! Raul -- Posted via http://www.ruby-forum.com/.