Saturday, September 29, 2012

Favor Composition Over Inheritance - Part 3





In part 2, I implement Duck with fly behavior. Now, I am going show how to add new behavior, quack . Let say, I want to add two quack behavior, Behavior::QuackLoud and Behavior::QuackSilent. Similar to fly behavior, each behavior is implemented in module, and put under directory [behavior].

...
 |+[behavior]
   |-...
   |-quack_loud.rb
   |-quack_silent.rb
The Behavior::QuackLoud is implement in quack_loud.rb module as shown here:
module Behavior
  module QuackLoud
    def quack
      puts "quack loud"
    end
  end
end
It's not hard to see how Behavior::QuackSilent is implemented.

Now, I want MallardDuck, which already be able to fly with wing, also can quack loudly. All I have to do is include Behavior::QuackLoud in the class MallardDuck. Of course, I need to require appropriate file:
require './duck'
require './behavior/fly_with_wing'
require './behavior/quack_loud'

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

In the same way, I can define duck that can fly but not quack, or duck that can not fly but quack loudly. Different duck with different behaviors can be defined by including appropriate behavior module. A particular behavior defined in one place, and can be easily shared between different class of duck. As you can see, it's easy to understand, implement, and maintain.

Let recap a bit: Share behavior of all kind of Duck are implemented in base class. Then different behavior are separated out into modules, and then get included into class definition when that class need  it. We can say, duck class is composed with different behavior module.

Here, how the composition is done in ruby using module!

Next time, I will use different way of implementation to allow a duck to change behavior during run time. It's would be fun!

Note: Amazon Prime & Flash



I migrate from Xbuntu to Crunbhbang Linux a couple days ago. Until today, I have not have a chance to test amazon prime video service yet. I try today, and guess what I can not watch video any more.

I look around for solution, and found this Ask Ubuntu page, which intern point to the Adobe support page that contains the solution. I make a copy over here for my own reference :)

Prerequisites for protected content playback


For Ubuntu 10.04 or later, ensure that the Hardware Abstraction Layer module is first installed using apt-get.
(Watch carefully for “hal” install errors, as a damaged package install can continue to affect video playback.)
sudo apt-get install hal
After the "libhal" (HAL) library install completes, close the browser and clear the Adobe Access directories by executing the following shell commands:
cd ~/.adobe/Flash_Player
rm -rf NativeCache AssetCache APSPrivateData2
Note:
If the Hardware Abstraction Layer module is missing, Flash Player still functions. However, it cannot play protected content that requires the Adobe Flash Access DRM (Digital Rights Management) module.

Note: Buildroid for VirtualBox

With is Buildroid for VirtualBox, I can have android 4.0.4 running on VirtualBox. All you have to do is download the ova file, one of the open visualization format. Import the file to VirtualBox, and turn it on!

It's good for the development, that for sure. If you like, you can just play around with it.

Crunchbang Linux and VirtualBox

Crunchbang is base on Debian. However, the virtualbox is a well known issue with crunchbang. When I try to install virtualbox from the repository (the OSE - Open Source version), it won't work out of the box. A quick googling, you would find couples link related to this issue.

One solution is to install official Oracle version, which you can follow the instruction found here: VARIOUS VIRTUALBOX INSTALLATION.

Unfortunately, after adding new source and apt-get update. I got this error messages:
W: GPG error: http://download.virtualbox.org wheezy InRelease: 
The following signatures couldn't be verified because the
public key is not available: NO_PUBKEY 54422A4B98AB5139

After quick googling again, I found this page, which provide me a solution:

gpg --keyserver pgpkeys.mit.edu --recv-key 54422A4B98AB5139
gpg -a --export 54422A4B98AB5139 | sudo apt-key add -

I believe that allow me to update Debian APT key. After these steps done, I can continue and finished the virtualbox installation. Anyway, before install virtualbox-4.1, I do "apt-get search virtualbox", and found that 4.2 also available. I just simply install 4.2 instead of 4.1.

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!

Thursday, September 27, 2012

Favor Composition Over Inheritance

I have been reading "Head First Design Patterns" [1], which used Java to construct all examples. It's made me wonder what would it take to implement same pattern in Ruby. What would be the different, specially Ruby is not "type" language at all.

The first pattern that I am going to try is "Strategy" pattern. The principal behind "Strategy" pattern is "Favor composition over inheritance". It's interesting to see that at least two different way we can implement this principal in Ruby. One using module, another using class.

Let use the same design in the book, the duck design. Since all duck would have name, and can swim. The Duck base class would contain attribute name and method swim(). All duck swim, you know.
class Duck 
  attr_reader :name
  def initialize
    @name = "simple duck"
  end

  def swim
    puts "All duck can swim."
  end
end

However, not all duck are fly in the same way. MallarDuck and RedheadDuck will be able to fly with wing, while ToyDuck won't be able to quack or fly at all. To be able to share same behavior between MallardDuck and RedheadDuck, we create a module under then namespace Behavior
module Behavior
  module FlyWithWing
    def fly
      puts "Fly with wing"
    end
  end
end

module Behavior
  module NotFly
    def fly
      puts "no way I can fly"
    end
  end
end

class MallardDuck < Duck
  include Behavior::FlyWithWing

  def initialize
    @name = 'Mallard duck'
  end
end

class RedheadDuck < Duck
  include Behavior::FlyWithWing

  def initialize
    @name = 'Redhead duck'
  end
end

class ToyDuck < Duck
  include Behavior::NotFly
  def initialize
    @name = 'Toy duck'
  end
end

irb> ducks = [MallardDuck.new, RedHeadDuck.new, ToyDuck.new]
irb> ducks.each(&:fly)
Fly with wing
Fly with wing
no way I can fly
With proper directory setup, and follow convention. Ruby will be able to find the file that contain module and include it properly with no configuration at all.

In this case, each module would contain in each file under directory "behavior". By ruby convention, filename would have to match the module name. That mean the file would be name "fly_with_wing.rb", and "not_fly.rb"

We can also do the same with "quack" behavior, say Behavior::QuackLoudly, Behavior::NotQuack, etc.

As you can see, we can use ruby module to implement composition quite efficiently. It's seem natural to me to use module to break down object into different component and composed them.

Next time, I will describe more in detail of the implementation.

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