第4回 2002/09/23

復刻第34弾!!4年まえ

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

【○】本日のお題 「システムはオブジェクト指向、そしてRubyで」(#004) ━━━━
                              福井修@Fsys

涼しくなりましたが、オブジェクト指向Ruby の時間です。
Webサイト構築にも「オブジェクト指向」がどんどん押し寄せています。

定評のある@ITでも「ここから始めるオブジェクト指向」が9/21連載開始ですね。
http://www.atmarkit.co.jp/fjava/devs/object01/object01.html

前回は、オブジェクト指向とは、次の認知概念によってモデル化し、実装する技術
「もの」の持つ機能による認知(これは何ができるものか)
「もの」の分類を行うことによる認知(これは何に似ているのか)
「もの」の構造による認知(これは何からできているのか)
でありオブジェクトに対するメッセージ(メソッドという)によって駆動するしかけが
オブジェクト指向の方式であることを説明しました。

オブジェクト指向プログラミングは、これまでその本流にはいなかったマイクロソフ
トも新しい製品の C#,VB.NET,そして9/11無償で公開されたJ#
http://www.microsoft.com/japan/msdn/vjsharp/downloads/download.asp
で、力が入っています。
それに伴い、以下のような解説記事などで「オブジェクト指向」そのものがますます
認知・普及してゆく様相です。

第3章 C#におけるクラスとインスタンス 2002/09/04
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_003/cs2_003_01.html
第4章 継承とインターフェイス 2002/09/11
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_004/cs2_004_01.htmlVB.NET移行の最大のハードルはオブジェクト指向プログラミング
http://www.atmarkit.co.jp/fdotnet/keyinterview/boc_kamata/kamata01.htmlVB .NETVBにあらず?――高まるプログラマーの懸念
http://www.zdnet.co.jp/news/0101/19/e_vb.html
第9回 オブジェクト関連(前編)2002/06/15
http://www.atmarkit.co.jp/fdotnet/vb6tonet/vb6tonet09/vb6tonet09_01.html
第10回 オブジェクト関連(後編)2002/06/22
http://www.atmarkit.co.jp/fdotnet/vb6tonet/vb6tonet10/vb6tonet10_01.html

オブジェクト指向は、もう避けては通れないでしょうから、覚悟を決めて乗り越える
しかないですね。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■ オブジェクト指向分析・設計続き クラスとクラス図
──────────────────────────────────────
オブジェクト指向には、ものの認知・モデル化という本質があり、オブジェクト指向
分析・設計に,UMLを利用しようというのが最近のトレンドであるという説明もしまし
た。その続きです。

ものの認知・モデル化というのは、なにもオブジェクト指向で始まったことではあり
ません。いわゆる『 設計(=デザイン) 』は、すべてそれがベースです。
ある固まりを表すのに名前をつけます。ものを認知・モデル化する基本は、『区別』
です。そしてその『区別』されたものに『名前』を付けてゆくのです。

赤ちゃんが、生まれるとまず『名前』をつけて他の赤ちゃんと『区別』できるように
します。実体は、その赤ちゃんなのですが、識別名として「ロミオ」^^;と名付ける
と他と区別してその実体を指し示すことができるようになります。
この場合は、赤ちゃんクラス(級・グループ・オブジェクト群)の1つの実体(オブ
ジェクト=インスタンス)は「ロミオ」という図式です。

この「ある固まりに名前をつけて管理する」やり方を「ある固まりを『クラス』とし
て認知し名前をつけて管理する」ようにしたのが、オブジェクト指向です。

繰り返します。「ある固まり(=もの=オブジェクト群)を認知し、『クラス』とし
て名前をつけてその単位で管理してゆく」のがオブジェクト指向です。

そして、分析・設計段階での『クラス』が、実装段階でも『クラス』として一貫して
利用できるのが、オブジェクト指向でのメリットのひとつなのです。

ある固まり『クラス』には「属性」と「振る舞い」が定義できるので、独立した存在
としてモデル化しやすいわけです。
『クラス』には『型(=いれもの=枠)』という側面もありますが、『動作(=振る
舞い)』も内蔵できるので、ひとつの独立した『もの』として取り扱えるのです。

『クラス』に対して、少しは親近感をもってもらえましたか?

『クラス』を具体的に表記し、さらにクラスとクラスの関連をクラス図として図解す
ることで、オブジェクト指向分析・設計が進められます。

クラス図の例
■ 初歩のUML 第2回 クラス図の詳細化とその目的 
http://www.atmarkit.co.jp/fjava/rensai/uml02/uml02.htmlUML技術者認定制度■チュートリアル中のクラス図
http://www.ogis-uml-university.com/tutorial/frm_datt.htm

では、実際の Rubyプログラミングの話の続きです。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■■   Rubyオブジェクト指向プログラミングの基礎 続き
──────────────────────────────────────
 環境整備は、前回 http://www.melma.com/mag/02/m00020302/a00000350.html 参照
■ オブジェクト指向 (class を使った) Ruby の続き

『クラス』の定義は 、class と end で囲みます。
 class クラス名
  〜
 end

『メソッド(振る舞い)』の定義は、 def と end で囲みます。
 def メソッド名
  〜
 end

 メソッドを決めて、その中の処理を記述してゆくのが、オブジェクト指向プログラ
 ミングのスタイルです。
 初期化メソッドメソッド名は、initialize と決まっています。
 この初期化メソッドは、インスタンス(=オブジェクト)の生成 ( new )の際に実
 行されます。

・ インスタンス変数の定義
 @hoge = fuga

 変数名の前に @ を付けるとインスタンス変数となり、インスタンス毎に有効です。

オブジェクト指向では、処理の入力としてデータを与えるのではなく、データ(=
オブジェクト)に、「処理せよ」と伝える(=メソッドを呼び出す)ことで、結果
を得ます。

前回の【 Windowsの場合 】の例を再掲します。
(注) 一行目は、cgi動作の際などで使用しますが、普通のスクリプトでは不要です。
・ oo.rb ソースファイル作成
#!c:\program files\ruby\ruby.exe
class Oo
  def initialize(x)
    @string = x
  end
  def println
    print @string, "\n"
  end
end

hello = Oo.new("オブジェクト指向スクリプトRuby!")
hello.println

・ 実行
> ruby oo.rb
オブジェクト指向スクリプトRuby!

……………………………………………………………………………………………………
これは、Ooクラスのインスタンス(=オブジェクト) hello を生成し、その インスタ
ンス(=オブジェクト) hello に対して メッセージprintln を伝える(メソッドを呼
び出す)ことで、結果を得ています。
……………………………………………………………………………………………………
これが、基本です。複雑・大規模になっても、この簡単な例が、理解できていれば
大丈夫です。
では、次にクラスを使うとうれしい例として「継承」をつかって「差分プログラミン
グ」をやってみましょう。Webのツボなので簡単に タグ を操作してみます。
【継承の例1】
・ oob.rb ソースファイル作成
require 'oo'
class Oob < Oo
  def printb
    print '',@string, '',"\n"
  end
end

inheri = Oob.new("Rubyは継承ができます")
inheri.println
inheri.printb

・ 実行
> ruby oob.rb
オブジェクト指向スクリプトRuby!
Rubyは継承ができます
Rubyは継承ができます

クラス oob は、クラス oo を親として『継承』した子クラスとして定義します。
class Oob < Oo
  :
end

class 定義で 親クラスを < でつないで記述すれば良いだけです。
親クラスが、別のソースファイルに存在するのであれば

require '親クラスの定義されたソースファイル名'

のように require 文でそれを指示します。

この oobのなかでは、initializeメソッドも printlnメソッドも定義していませんが
ooクラスを『継承』しているので、その親クラスで定義されたメソッドは、子クラス
で、メソッド自体は1行も書かずに使えるのです。

printbメソッドは、初期化で生成した文字列の前後に,タグを付加しています。

注)実行結果の1行目は、ooソースを requireで呼び出した際に、そこで実行される
スクリプトの結果です。(実務的には、親クラスからはそのような行は、除いておけ
ばよいのですが、文脈上例をそのまま使っている為の副作用です。)

【継承の例2 メソッドのオーバーライド】
・ ooc.rb ソースファイル作成
require 'oo'
class Ooc < Oo
  def println
    print '',@string, '',"\n"
  end
end

inheri = Ooc.new("Rubyはオーバライドもできます")
inheri.println

・ 実行
> ruby ooc.rb
オブジェクト指向スクリプトRuby!
Rubyはオーバライドもできます

今回は、クラスOocでクラスOoを継承し、親クラスの同名のメソッドprintlnを定義
しました。そうすると、親クラスには、一切手を触れることなく、メソッドに新た
な機能(この場合は、前後に,タグを付加)を付加することができるのです。

このように親クラスのメソッドを子クラスで同じ名前で定義して、そちらを優先し
て使わせるということができるのです。これをオーバライドといいオブジェクト指
向の特徴の『多態性』の具体例のひとつです。

super を使うと親クラスの同名のメソッドを使うことができますので、使い分けも
もちろん可能です。
http://www.ruby-lang.org/ja/man-1.6/?cmd=view
;name=%A5%E1%A5%BD%A5%C3%A5%C9%B8%C6%BD%D0%A4%B7#super
↑一行で続けて下さい

続く....

【おまけ】
Ruby で ViewとModel,Controllerを分離して制御できるライブラリが公開されました。
著者のうえのさんは、相棒です。
■ Wakaba
http://www.ruby-lang.org/en/raa-list.rhtml?name=Wakaba

■ Wakabaを利用した郵便番号・事業所検索
http://fsys.net/nw/post.rb/

LAMP(Linux,Apache,MySQL,PHP/Perl/Python)というジャンルが確立されつつあります。
LARP(Linux,Apache,Ruby,PostgreSQL)もどんどん行きたいものです。
WARM(Windows,Apache,Ruby,MySQL)も熱くなったりして :-)

【プロフィール】
福井 修 ( FUKUI Osamu )o-fukui@po.iijnet.or.jp
福井システムリサーチ http://fsys.net/  主幹。システム構築歴25年。
日本リヌクス協会、神戸商工会議所情報処理学会 会員
関西ソーホ・デジタルコンテンツ事業協同組合流通科学大学 委託SE http://www.umds.ac.jp/
デジタルハリウッド三宮校 Java講師