図1●複数のクラスを1つのクラスに見せかけるFacadeパターン。もともと三つのクラスを使う必要がある機能(a)を,Facadeクラスによって一つのクラスに見せかけることができる(b)
図1●複数のクラスを1つのクラスに見せかけるFacadeパターン。もともと三つのクラスを使う必要がある機能(a)を,Facadeクラスによって一つのクラスに見せかけることができる(b)
[画像のクリックで拡大表示]

 IT Proに、アラン・ケイ氏が2003年1月に来日した際のインタビュー記事があります。それによると、氏は、生物の細胞が複雑な構造を作り上げる様子からヒントを得て、オブジェクト指向を考案したそうです。細胞から細胞へメッセージを送る(メッセージ・パッシングする)ことで、目的の機能が実現されると考えるのです。筆者のような凡人には、思いもよらない奇抜な発想ですね。細胞は、プログラムにおけるオブジェクトに相当します。メッセージを送るとは、他のオブジェクトが持つメソッドを呼び出すことです。こう言ってしまうと、実に味気ないのですが。

 アラン・ケイ氏は、1972年にSmalltalkというオブジェクト指向プログラミング言語を開発しました。今から30年以上も前のことです。現在でもSmalltalkのファンが大勢いて、俗に「スモールトーカー」と呼ばれています。とにかくオブジェクト指向が好きで好きでたまらないという連中です。筆者の友人の中にも、1人だけスモールトーカーがいます。N氏です。

 数年前になりますが、プログラムの構成要素は何か? というテーマで、N氏と議論したことがあります。筆者の考えは「プログラム=処理+データ」で、N氏の考えは「プログラム=オブジェクト+メッセージ」でした。スモールトーカーは、根本的に発想が違うのです。

 前置きが長くなりましたが、今回はメッセージ(味気ない言い方をすれば、メソッド呼び出し)に関係した便利なパターンを紹介します。

【お役立ち度】★★★★★
●1つのメッセージを複数のクラスで処理するFacadeパターン

 これまでに何度も繰り返し言ってきたことですが(読者の皆さんは、耳にタコでしょう)、複数のプログラマが1つのシステムを構築する場合には「私はクラスを作る人、貴方はクラスを使う人」という役割分担ができます。クラスを作る人は、クラスを使う人に楽をさせるための工夫をしましょう。それが、オブジェクト指向プログラミングを効果的に実践するための秘訣です。「思いやり」が大事なのです。

 クラスA、クラスB、クラスCという名前の3つのクラスを作ったとします。3つのクラスが持つメソッドを呼び出すことで、ある目的が達成されます。クラスを使う人は「3つもクラスを使うなんて面倒だなぁ」と文句を言います。それなら、ちょっと工夫をしてみましょう。3つのクラスを使うクラスDを作るのです。クラスを使う人は、クラスDだけを使えばよいことになります。簡単なことですが、実に素晴らしいアイディアでしょう。

 クラスDのように、複数のクラスを使うことを1つにまとめたものを「Facadeクラス」と呼び、Facadeクラスを使ったプログラムの構造を「Facadeパターン」と呼びます。Facade(ファサード)とは「見かけ」という意味です。内部的に複数のクラスを使っているのに、それを使う側には1つに見せかけているのです(図1[拡大表示])。

 クラスを作る人には、クラスDを作る作業が増えますが、その分だけ、クラスを使う人が楽できます。クラスを使う人への思いやりに溢れたFacadeパターンの評価は、文句なく星5つの満点です。

【お役立ち度】★★★★
●1つのメッセージを伝言ゲームのように処理するChain of Responsibilityパターン

 一昔前に「ぷよぷよ」というゲームが流行ったのを覚えていますか? 筆者は、克明に覚えています。なぜなら、某専門学校でパソコン実習の非常勤講師をしていたときに、一部の学生が授業中にこっそり遊んでいたからです。「やった連鎖だ!」なんて小声で言いいながら喜んでいる様子を思い出します。連鎖とは、画面に積み上げられたダンゴのようなキャラクタが、まとめて落ちて消えることです。「お前ら、授業中にゲームなんかやってないで、ちゃんと先生の話を聞け!」連鎖という言葉を聞くと、今でもムカムカしてきます。

 これから紹介するChain of Responsibilityパターンを直訳すると「責任の連鎖」となります。「メッセージの連鎖」と考えればわかりやすいでしょう。最初にオブジェクトAがメッセージを受け取り、それをオブジェクトBに送り、そのメッセージをオブジェクトBがオブジェクトCに送り...ということを何度か繰り返すのです。「ぷよぷよ」を例にすれば、一番上に乗ったダンゴが「落ちろ」というメッセージを最初に受け取り、それを下のダンゴたちに伝言ゲームのように送って行くのです。これが、Chain of Responsibilityパターンです。

 ムカツク思い出だからというわけではありませんが、Chain of Responsibilityパターンの評価は、星4つとさせていただきました。連鎖を深めて行くと、それだけ関連するオブジェクトを増やしてしまい、プログラムの構造を複雑にしてしまう危険性があるからです。「このメッセージは、いったい誰が処理しているんだ」ということになり、保守性が低下してしまいます。

 「ぷよぷよ」の例は極端でしたが、皆さんの身近なところでもChain of Responsibilityパターンが使われています。それは、GUIのイベント処理です。たとえば、ウインドウに表示されたボタンがクリックされたときに、Button_Click ( ) というメソッドが呼び出されるプログラムがあるとしましょう。最初にボタンが受け取った「お前をクリックしたぞ」というメッセージは、クラスライブラリが提供するボタンクラスで処理されるのではなく、皆さんが記述したクラスのButton_Click ( ) に送られて処理されます。Button_Click ( ) の処理として、さらに別のクラスのメソッドを呼び出すこともあるでしょう。

 このように、メッセージを他のクラスのオブジェクトに送って処理してもらうことを、OOP用語で「委譲」と呼びます。そう言えば、.NETプログラミングで使われるC#やVisual Basic .NETなどの言語では、イベント処理を行うメソッドへのポインタのことを「デリゲート」と呼んでいますね。デリゲート(delegate)とは「委譲する」という意味です。すなわち、Chain of Responsibilityパターンを実現するには、メッセージの送り先のオブジェクトのポインタ(「アドレス」や「参照」とも呼ぶ)を知っている必要があります。具体的には、クラスのメンバの中に、送り先のオブジェクトのポインタを格納するフィールドを用意しておけばいいのです。サンプルコードは示しませんが、何となくイメージできますよね。

 次回は、BuilderパターンとPrototypeパターンを紹介します。

矢沢久雄

グレープシティ株式会社(http://www.grapecity.com)アドバイザリースタッフ

表紙ページへ