Saturday, September 29, 2012

Favor Composition Over Inheritance - Part 2

In previous post I show how to do composition using Ruby Module. It's quite natural and easy to do. I also mention Ruby Convention on class/modules code organize, but I have not made it clear what it really means. Let get into this topic today. If you have not read the previous post , I recommend skim though it to get the idea.

By following ruby convention, each class have it own separated files. The namespace become a sub-directory, which contains module files. In this case directory behavior contains different fly behavior
+[duck_app]
 |-duck_app.rb
 |-duck.rb
 |-mallard_duck.rb
 |-redhead_duck.rb
 |-toy_duck.rb
 |+[behavior]
   |-fly_with_wing.rb
   |-not_fly.rb

The duck_app.rb is the main application which using ducks class. Here how it's look like:
require './mallard_duck'
require './redhead_duck'
require './toy_duck'

ducks = [MallarDuck.new, RedheadDuck.new, ToyDuck.new]
p ducks.map(&:name)
ducks.each(&:swim)
ducks.each(&:fly)
In this case, we simply ask their name. Let they swim and fly.

In order to use class MallardDuck, we have to tell ruby where is the MallardDuck definition are, by using "require" statement as showed. Similarly, in the mallard_duck, which reference to Duck, and Behavior::FlyWithWing symbols, we use 'require' statement to load the symbols definition:
require './duck'
require './behavior/fly_with_wing'

class MallardDuck < Duck
  include Behavior::FlyWithWing
  ...
end

With this convention, the code is organized into well defined places, which make it easy to find things.

That's it, for today!