From: Dave Burt Date: 2005-08-12T06:21:10+09:00 Subject: Re: Head First Design Patterns - Strategy Pattern [was: Java/C# "interface" in Ruby ?] Peter Fitzgibbons wrote: > ... > My question is this: The :quackDelegate and :flyDelegate are written in > Java/C# as object instances of an interface. Clearly I've ditched the > interface itself, but the rest is pretty much as described in the book. This looks like exactly what mixins are for - you can put the implementation itself in a module and then include it rather than using delegation and having extra objects with one-method floating around. class Duck def swim() "All ducks float, even decoys!" end end module FlyWithWings def fly() "I'm flying!" end end # other Flys and Quacks as above, the only change is class -> module... class MallardDuck < Duck include Quack include FlyWithWings end class ModelDuck < Duck include FlyNoWay include Quack end # next file, duck_test.rb require 'test/unit' require 'duck' class DuckTest < Test::Unit::TestCase def testMallard mallardDuck = MallardDuck.new assert_equal "Quack", mallardDuck.quack # no intermediate method needed assert_equal "I'm flying!", mallardDuck.fly end def testModelDuck modelDuck = ModelDuck.new assert_equal "Quack", modelDuck.quack assert_equal "I can't fly", modelDuck.fly modelDuck.extend FlyRocketPowered assert_equal "I'm flying Rocket Powered!!", modelDuck.fly end end And there you have it - much nicer! If you do want to use delegation (I don't know why), you can use a class with a single class- (like Java static-) method; then you don't need to use FlyWithWings.new, you just pass the FlyWithWings class: class FlyWithWings def self.fly() "I'm flying!" end end # ... (only changes are "def fly()" -> "def self.fly()") class MallardDuck < Duck def initialize @flyDelegate = FlyWithWings # ... (only changes are "= FlyWithWings.new" -> "= FlyWithWings") Cheers, Dave