2004年4月29日号

━━━━━━━━━━━━━━━━━━━━━ 2004.04.29 Vol.954 ━━━━━
 ■□■□■
 ■□■□■ 日刊「WEBのツボ!」
 □■□■□              http://www.soho-union.com/
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                             配信部数 3266部

「続 システムはオブジェクト指向 Ruby & Flash」(#008)
                                                        福井修@Fsys.NET

【○】本日のお題 「 クラスの生成と部品の利用 」    ━━━━━━━━━━

さあ今年もゴールデンウィークがやってきました。何か楽しいですね。
こんにちは、Fsys福井システムリサーチの福井です。

前回「続入力チェックと部品化Mix-in」注1)にて複数の継承には、Mix-inという
方式が有利と説明しました。また

    『 繰り返すことの大切さ 』
    
も説きましたので、復習でこの言葉も繰り返しておきます。:-p

DELLの『 繰り返し.. 』に観念して、Pen4&17inch&DVD-RWを仕入れて今、新マシ
ンでこの原稿を書いています。バックには、iTunes 注2)の演奏が流れています。

PC-9801の時代の20MB(くれぐれもGBではありませぬぞ)のHDの値段で、この マシ
ンが買えるというすごい時代になったものです。

さて今回は、オブジェクト指向の具体的なメリットの部品化の実装についてもう
少し語ります。

ノートPCにWindowsXPという環境で、どんどん楽しいプログラムを進めましょう。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ Mix-in 復習  (くり返しが大事なんですってばぁ^^)
────────────────────────────────────
前回 月の最大日 を求めるメソッドを含むモジュールを紹介しました。
共通モジュールを1つ作成して、必要なクラスでそれを利用するのです。

モジュールとクラスは似ていますが、次の点で異なります。
  1) モジュールは、インスタンスを持つことができない
  2) モジュールは、継承できない
  3) モジュールは、複数クラスの共通差分を持つ

  プログラムの部品化は、永遠のテーマで、共通部品をくくりだすのにいろいろ
 な方式があります。
  FORTRAN では「サブルーチン」という 名前でした。
  C言語では「関数」という名前です。 「共通関数」などと呼んでいました。
  「ライブラリ」や「共通モジュール」という呼び方もありました。
  Windowsの.dll(ダイナミックリンクライブラリ)などはその例そのものですね。

  昔 中学で 因数分解を学びました。もっとも基本的な例ですが

  Ax + Bx = x(A + B)

  共通因子(この場合 x )を括り出してから利用することで、 同じ処理を何度も
  書かないで済みますし、変更があった場合も1ケ所直すだけで済む訳です。

  まあわかり切ったことを書きましたが、オブジェクト指向のクラスでこれを
  どう実装するかというのはテーマになります。 Javaですと interface と継承
  を組み合わせて実現しますし、Rubyでは、モジ ュールを Mix-in します。

 --------------- ここから util.rb -------------------
module Input_check

  # 年月よりその月の日付のmaxを得るメソッド
  # 次の月の1日の前の日付けが、これすなわちその月の最大日
  def days_in_month(year,month)
    month += 1
    if month == 13
      year += 1
      month = 1
    end
    (Time.local(year, month, 1) - 24*60*60).mday
  end
end
 --------------- ここまで util.rb -------------------

この共通部品を、include で クラスに取り込みます。
そのクラスから生成したオブジェクト(=インスタンス)のメソッドとしてmodule
で定 義したものが使えます。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ クラスを作る
────────────────────────────────────
ここから オブジェクト指向のひとつの壁であるところの自分でクラスを作る話
に進みます。

前に 「クラスは、『設計図』であり、『たこ焼き器』であり、手続き(=メソ
ッド)と データ(=プロパティ)をまとめたところの『くくり(=管理単位)』
だ」と語りました。注3)

実際のクラスの実装を見てみましょう。

クラスは 

class Hogehoge
  〜
end

で定義します。クラス名の先頭は大文字です。

Mix-inで クラスに、別モジュールで定義されたものを持ち込むには include し
ます。

 --------------- ここから check.rb --------------------
require 'util'

# 日付チェック
class Date_check
  include Input_check     # モジュールをインクルード
end

c = Date_check.new        # クラスのインスタンス生成

p c.days_in_month(2004,2) # 例として 2004年2月の Max日出力

 --------------- ここまで check.rb --------------------
util.rb と check.rb を同じフォルダに設置し

> ruby check.rb

で 29 が出力されれば OK です。


これは、シンプルにするために、クラスの中身は include のみという変則的な
例でしたが、次は、クラスにメソッドも定義します。
暦を扱っているのでカレンダの生成例です。

 --------------- ここから calendar.rb --------------------
require 'util'

class Calendar
  include Input_check    # モジュールをインクルード

  # 年月よりカレンダ生成
  def calendar_table( year,month )
    emptystr = "   "
    daycount = days_in_month(year,month)  # 該当月の最大日
    lines    = [ sprintf("%8d 年 %d 月", year, month),
                         " 日 月 火 水 木 金 土" ]
    line     = nil
    w = Time.local( year, month, 1 ).wday # 月初めの位置
    # 月の日数分繰り返し
    (1..daycount).each {|d|
      line ||= Array.new( 7, emptystr )
      line[w] = sprintf( " %2d", d )
      if w == 6 then
        lines << line.join
        line = nil
      end
      w = (w+1) % 7                       # 位置更新
    }
    lines << line.join if w > 0
    return lines.join("\n")
  end
end

c = Calendar.new   # calendarクラスのインスタンス(=オブジェクト)を生成

puts c.calendar_table(2004,4)
puts c.calendar_table(2004,5)

 --------------- ここまで calendar.rb --------------------

実行してみるには、util.rbとcalendar.rbを同じフォルダに設置し

 > ruby calendar.rb

と起動します。


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ まとめ
────────────────────────────────────
 今回は クラスの生成と部品の利用というテーマで、Mix-in方式の、 moduleで
定義したメソッドをクラスに組み込む例を解説してみました。

モジュールで別ファイルに共通要素を括り出して部品化する実装は、いかがでし
たでしょうか。 

共通モジュールをクラスに組み込めるというのがポイントです。

実装レベルのクラス設計の際には、デザインパターンを参考に美
しい実装を目指したいところです。

カレンダの実装例は、前にも注4) 紹介しましたが、今回は、Mix-inでの部品化
に 進化しています。

「 繰り返して 磨けば 光る 」

またまたいろいろな要素が出てきましたね。一歩一歩進みましょう。

また 次回をお楽しみに。
  
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
※ 注釈、資料、参考情報
────────────────────────────────────
注1) 続 システムはオブジェクト指向 Ruby & Flash (#007)
    「続入力チェックと部品化Mix-in」
http://www.melma.com/mag/02/m00020302/a00000740.html

注2) iTunes デジタルミュージック・ジュークボックスソフトウェア
http://www.apple.co.jp/itunes/overview.html

注3) システムはオブジェクト指向 Ruby & Flash (#002)
    「オブジェクト指向とは」
http://www.melma.com/mag/02/m00020302/a00000602.html

注4) 「システムはオブジェクト指向 Ruby & Flash」(#005) 2003.10.02 Vol.836
     MVCモデル を Ruby&ActionScript で実装する
http://www.melma.com/mag/02/m00020302/a00000631.html

【プロフィール&近況】
福井 修 ( FUKUI Osamu ) o-fukui@po.iijnet.or.jp
福井システムリサーチ http://fsys.net/  主幹。システム構築歴27年。
システム構築エキスパート
日本Linux協会、神戸商工会議所情報処理学会、関西IT共同体 会員
関西ソーホ・デジタルコンテンツ事業協同組合
<