Sunday, September 30, 2012

Favor Composition over Inheritance - Part 4

Previously in the programming series posts, I show how to use module to implement composition. One limitation of using module is, duck can not change behavior at run time. Such as MallardDuck can only fly with wing. How can we allow an instance of duck to change their behavior at run time? An answer is using object instead of module.

 To support this feature, the base class, now, hold all the behaviors  implemented for subclass. That quite different from using module, which the base class know nothing about subclass behaviors at all.
class Duck
  attr_reader :name
  attr_accessor :fly_behavior, :quack_behavior
  def initialize
    @name = "mallard duck"
    @fly_behavior = nil
    @quack_behavior = nil

  def fly

  def quack

In this case, the base class by default has no behaviors. It's the subclass job to create, and assign default behaviors of the subclass when initiate an instance. For example, MallardDuck default behavior for flying is fly with wing, etc.
require './duck'
require './behavior/fly_with_wing'
require './behavior/quack_loud'

class MallardDuck < Duck
  def initialize
    @name = "mallard duck"
    @fly_behavior =
    @quack_behavior =

For the behaviors, instead of module, it's become a class.
module Behavior
  class FlyWithWing
    def fly
      puts 'Fly with wing.'

Here an implementation of duck_app.rb. This example show an instance of MallardDuck, which first can fly and then the same duck can not fly any more when the behavior re-assigned. It still quack loadly thou.
require './mallard_duck'
require './behavior/not_fly'

mduck =

mduck.fly_behavior =

Here you have it! A duck that can change behavior at run time.

This implementation of composition is quite similar to java "interface" implementation using in the head first design pattern book [1]. To be almost exactly the same, we would duplicate fly, and quack method all over the sub-classes. That is some how a give and a curse of ruby!

I still one more to go on this topic, a comparison for module and object approaches. Stay tuned!

[1] Head First Design Patterns, Eric Freema, Elisabeth Freeman, O'Reilly 2004.

No comments:

Post a Comment