「オブジェクト指向」という言葉は世の中に広く出回っていますが、「オブジェ クト指向って何?」という質問に的確な答えが返ってくる事は多くはありませ ん。「オブジェクトとは『もの』のことだよ」と言われても、正直言ってさっ ぱりわかりません。そしてそれ以上の事を聞くと「例えばJavaではねぇ……」 と特定のプログラム言語の話になってしまいます。
ここでは、「オブジェクト指向だとどんなメリットがあるか」でも「オブジェ クト指向言語の文法」でもなく、そのものずばり「オブジェクト指向とは何か」 について考えてみたいと思います。
まずはストレートに「オブジェクトとは何か」という問いを発してみましょう。 これは難問です。そして人によって解釈の違う概念でもあり、「これで正解」 というものがないのも実状です。しかし敢えてこの問いに一つの答えを出して みたいと思います。
「オブジェクト」とは日本語で言えば「もの」です。しかし「もの」というだ けではそれこそ何でもオブジェクトになってしまいます。「何でもオブジェク トだ」という見方も一つあるのですが、ここではそれに「アイデンティティー」 という考え方を導入したいと思います。 「アイデンティティー」は日本語では「自己同一性」と訳されますが、「それ がそれであること」です。人間で言えば「自分が他の人とは区別された自分自 身であること」です。そしてアイデンティティーを備えた「もの」こそが「オ ブジェクト」なのです。
例えば薬局に錠剤の入った薬瓶が並んでいる所を想像して下さい。それぞれの 薬瓶には名前の書かれたラベルが貼ってあり、錠剤がたくさん入っています。 これらの薬瓶は取り換えの効かないものです。頭痛薬の入った瓶と胃腸薬の入っ た瓶は混同してはいけないものですし、同じ薬の入った瓶でも中身の多いもの と少ないものではまた違います。こういう、それぞれの瓶が他の瓶と取り換え が効かない固有の特徴を持っているという状態が「アイデンティティー」を持 つということです。それに対してその中身はどうでしょう?瓶の中には同じ 薬の錠剤がたくさん入っていますが、どの錠剤も他の錠剤とまったく同じで取 り換えが効きます。これがアイデンティティーのない状態です。
アイデンティティーのあるなしを見分けるには、「個体が識別できるかどうか」 を考えるとよいでしょう。アルバイト店員が薬剤師に「薬瓶を持ってきて」と 頼まれたとしましょう。アルバイト店員が「どの薬瓶ですか?」と聞くと、薬 剤師は例えば「一番上の棚の右から3番目のところにある『アスピリン』と書 いてある瓶を持ってきて」というように答えるでしょう。薬剤師は指定した場 所にある特定の薬瓶を持ってきてほしいのです。
それに対して「アスピリンの錠剤を10個持ってきて」と言った場合はどうなる でしょう?「どこに入っていますか?」と聞かれた時、「『アスピリン』と書い てある瓶に入っているから」と答えたならば、薬剤師はその瓶に入っている錠 剤ならどれでもいいのです。もし薬剤師がそれぞれの錠剤を識別しているとし たら、瓶に入っている「どの」錠剤が欲しいかを言うことでしょうし、それが できるように錠剤に通し番号が刻印されているでしょう。実際には錠剤はどれ も同じで全く見分けがつかないから個体識別はできません。そしてそれはアイ デンティティーがないということなのです。
もし薬局の棚の一段分が全部アスピリンの薬瓶であって、単に「アスピリンと 書かれた瓶を持ってきて」と言われたとすれば、瓶自体にもアイデンティティー はありません。薬剤師にとってはどの瓶だろうが関係ないわけなのですから。
アイデンティティーの概念が「違い」を強調する概念だとすれば、クラスの概 念は「同質性」を強調する概念です。上で「薬瓶を持ってきて」「どの薬瓶で すか?」というやりとりがありました。この時の「薬瓶」というのがクラスで す。個々の薬瓶はそれぞれにアイデンティティーがあって他の薬瓶とは違いま すが、すべての薬瓶は「薬瓶である」という意味では同じなのです。
薬瓶すべてに共通する同じような性質があってこそ、それぞれの薬瓶の違いを あれこれ言う意味もあるのです。人間だってアイデンティティーについて悩む 時には他の人との違いについて悩みます。誰もコップやテーブルとの違いにつ いて悩んだりはしません。「同じようなものであって実は違う」というのが重 要なのです。
クラスという同質性を強く意識した場合に、同じクラスの中での個々の物体を 示す言葉として「インスタンス」という言葉を使います。「薬瓶」というクラ スに対して、個々の薬瓶のことを薬瓶のインスタンスと呼びます。これに対し て、「オブジェクト」という言葉は、こうした使い分けをあまり意識せずに、 単に「もの」という意味で使います。
さて、オブジェクトとは「同じ性質を持つクラスの中でそれぞれのインスタン スが識別されること」であると述べました [1] 。それぞれのインスタンスのどこがどう違うのかというのを述べるのがオブジェ クトの「属性」です。 薬瓶の場合、それがどこに置いてあって中に何の錠剤がどれだけ入っているの かというのが属性です。「中に錠剤が入っている」という性質は同じでも、何 がいくつ入っているのかはそれぞれの薬瓶で違うというわけです。
それでは、属性の値がまったく同じならそれは同じものとして扱っていいので しょうか?例えば同じ形の瓶でアスピリンが同数入っている瓶が2つあったと したら、その2つの瓶の区別はどうすればいいのでしょうか?それとも区別は つけなくていいのでしょうか?それに対する答えが「識別子」という概念です。
属性の中で、特にインスタンスを見分けるためのものを識別子といいます。も し薬局がそれぞれの瓶に管理番号を振っていれば、「3番の瓶」と言うだけで 特定の瓶を持ってくることができます。そうでなくてもしまう位置が決まって いれば「一番上の棚の右から3番目の瓶」というように指定することができま す。この場合は「瓶の置いてある位置」が識別子です。つまり、数あるインス タンスの中から特定の一つを見分けて指し示すことができるものが「識別子」 です。
さて、識別子という言葉を説明したところで、前述の「属性の値がまったく同 じならそれは同じものとして扱っていいのでしょうか?」という問いに答えま しょう。それは私に聞くべき問題ではなく自問自答すべき問題です。もし区別 ができなくて困るのだったら、それぞれの瓶に番号を振るなりしまう位置を決 めておくなりすべきです。そして、瓶の通し番号やしまう位置を「属性」とし て加えましょう。結果としてそれぞれの瓶がまったく同じ属性の値を持つこと はなくなります。
もし属性の値がまったく同じ2つの瓶の区別をつけなくていいのでしたら、そ の二つの瓶は交換可能であり、つまりはアイデンティティーがないのです。だ からそれはオブジェクトではありません。 つまり、前述の問いの答えは「それがオブジェクトなら少なくとも一つは識別 子を持つ必要があるから、属性の値がまったく同じになる事はあり得ない」と いうわけです。
識別子が複数存在することもあります。瓶に通し番号を振ってさらにしまう位 置も固定すれば、「通し番号」と「位置」の2つの識別子を持つことになりま す。使用者はどちらを使ってもよく、それだけ便利に使うことができます。
ただ、識別子の多くは内部番号になるという点に注意して下さい。瓶に振る通 し番号は別に1から順番でなくてもいいし、数字ではなく文字であっても構わ ないのです。単に違ったマークさえついていればいいのですから。そしてプロ グラミング言語上ではすべてのオブジェクトにはポインタという通し番号がつ けられます。だから、単なるマークでいいのなら識別子は「内部の通し番号」 としておいて下さい。そうすればプログラマーが都合がよいように自由につけ られます。
「識別子」という概念があまり一般的でないのはこの事情があるか らでしょう。何も言わなければプログラミング言語が勝手につけるからです。 しかしオブジェクトの本質がアイデンティティーにある以上、それを識別する ものとして識別子というのは重要な概念です。
オブジェクトとは目に見えて触れることができる「もの」だけではありません。 概念もまた立派にオブジェクトになり得ます。例えば「アスピリン」というの もオブジェクトです。「アスピリン」という概念はある薬効を持つ特定の化学 物質を指す言葉です。そしてそれはその名前でもって他の薬とは区別されます。 それは「薬」あるいは「薬の種類」というクラスのインスタンスです。
物質的な「もの」より「概念」の方がオブジェクトとして考えにくいかもしれ ません。しかし「もの」と同じ法則を適用すればいいのです。同じ種類のオブ ジェクトを集めたクラス(「薬」)があり、それぞれを区別する識別子(上の例 では「名前」)があればいいのです。そしてそこには属性(「化学式」や「薬効」) があります。
今までオブジェクトとは何でどういう性質を持っているものかを説明しました。 そしてアイデンティティーがないといけないという話もしました。しかしアイ デンティティーがあるかどうかというのは見方によって変わる話です。例えば 薬瓶に通し番号を振って区別しなくてはならないか、それともアスピリンの瓶 ならどれも同じでいいか、といった話です。どういう立場でシステムを見るか というのを「問題領域」あるいは「ドメイン」と呼びます。
同じシステムでも立場が違えば見方が違い、そして何をオブジェクトとするの かも違ってきます。薬剤師は薬を「アスピリン」のように名前で識別するのに 対し、仕入担当者は製薬会社の商品コードだけが重要でそれがどの薬でどんな 効用があるのかはどうでもいいかもしれません。単位も錠剤単位ではなく瓶の 数、あるいはケース単位かもしれません。人によってどのレベルまでは個体識 別が必要でどこから先は同じものとして扱っていいのかは違ってきます。それ を区別するのがドメインです。
ドメインを意識しないと、往々にしてすべての人の立場を全部盛り込もうとし てしまいます。そして「これはオブジェクトかどうか」という議論が起きます。 「これは○○の人にとっては重要だ」「いや、○○の人にとっては重要ではな い」と。これはどちらの意見も正しいのですから、当然のことながら平行線を たどります。そもそもの間違いはこれらを同時に議論することなのです。
オブジェクトについて考える時には常にそのドメインについて考えましょう。 「どういった観点から考えるのか」ということです。
要するに、オブジェクトとは同種の他のものと区別することができる「個体」 のことなのです。そしてそこにはどの点で違うかという「属性」と、どの点で 同種だと言えるかという「クラス」があります。これだけを理解できたら、 「オブジェクトとは何か」を理解したことになります。
「オブジェクト」とは何かという話をした後にいよいよオブジェクト指向とは 何かの話に移りたいと思います。オブジェクト指向とは要するに今まで述べた ようなオブジェクトを中心に考えていこうというだけの事に他なりません。そ してこれだけを言うと「なんだ、当たり前のことじゃないか。なぜ今さらこん な事を言うんだ?」と疑問に思うかもしれません。だからまず経緯として構造 化手法について話をしましょう。
ソフトウェア開発の分野で、「オブジェクト指向」の前によく言われていたの が「構造化手法」です。構造化手法のスローガンを一言で言えば「意味のある 単位にまとめよう」というものです。関数としてまとめ、構造体としてまとめ、 そしてライブラリとしてまとめます。そうすることによってプログラムがより わかりやすく書きやすくなりますというのが「構造化」の教えです。
構造化手法は一つの意識改革でした。それまでプログラムというのは「コンピュー タを動かすためのもの」であり、動きさえすれば何でもよかったのです。そ こに「人間がプログラムを見た時の見易さも考えよう」と言い出したのです。 そしてそのためにプログラムを関数という「部品」に分割し、それぞれについ てさらに詳しく考えていくことを提唱したのです。
構造化手法の考え方は今では当たり前のように受け入れられています。わかり やすいような関数の分割の仕方を考える事や、関数の集まりであるモジュール の分け方を考える事はだれでもやっている事でしょう。モジュールの構造図や データフロー図まで書いたことがある人は少ないかもしれませんが、やってい る事は同じ事です。
構造化手法が当たり前になった今、構造化手法とは何かを認識するにはそんな もののなかった昔に一度戻ってみる必要があります。それは、Basic(Visual Basicではない)やCOBOLやFORTRAN(これも今のものではなくできた当時のもの)、 あるいはアセンブラでプログラムを組んでみることです。これらの言語で行番 号の管理やGOTO文の嵐に出くわせば、今の言語がどのくらいありがたいかがわ かるはずです。「GOTO文は悪」とか「フローチャートを書け」とか「コメント をつけよ」という教えもその意味がわかるはずです。 [2]
構造化の考え方は「処理を部品に分割する」というやり方でした。どういうプ ログラムを作りたいかがまずあって、それを実現するにはどうすればいいかを 考えていたのです。しかしプログラムの規模が大きくなるにつれて別の問題が 生じてきました。「どういうプログラムを作りたいのかがよくわからない」と いう問題です。処理を部品に分割しようにも、そもそも処理自体があいまいに なってきてしまったのです。
これを解決する手段として、「内部処理(プログラム)はとりあえず忘れて、外 から見える事象についてだけを考える」という方法が提唱されました。プログ ラムではなく実世界を対象にして「どう処理するか」ではなく「どういう処理 をさせたいのか」だけを考えようというのです。研究対象がプログラムではな く実世界なので、関数とか構造体の代わりにオブジェクトという概念を導入し ました。
今までの考え方では、プログラムにどういう処理をさせたいのかということか ら分析が始まりました。例えば薬を管理するには「買ってきた薬を登録する」 とか「薬瓶を棚にしまう」とか「薬瓶から薬を取り出す」といったような「処 理」がまずあって、これらの処理を実現するのにどう関数に分割するかを考え るという順序でした。しかしオブジェクト指向ではとりあえず管理ソフトのこ とは忘れて、管理対象である薬と薬瓶について考えます。薬とはどういうもの で薬瓶とはどういうものか、そして我々はそれをどう扱うのかについて考えま す。構造化手法が内部からの視点であるのに対してオブジェクト指向は外部の 視点であると言えるでしょう。
今まで「プログラムのことは忘れましょう」と述べてきましたが、「俺は作り たいのはプログラムで、それ以外の何物でもないんだ」と思う方もおられるで しょう。オブジェクト指向では、従来の「プログラム中心」の考え方そのもの を改める必要があります。ここではそれを「手続き的」と呼びます。
そもそも「プログラム」とは何でしょう。ある見方で言えばこれは「コンピュー タに対する命令」です。例えば表計算ソフトである列の合計を計算したいとし ます。これは人間がコンピュータに「列1の合計を計算してこのセルに値を入 れろ」と命令するという図式です。これを「手続き的」と形容します。
それに対して別の考え方があります。「このセルは列1の合計が入るセルであ る」と定義するという図式です。これは命令ではありません。これを「宣言的」 と形容します。「手続き的」と「宣言的」は言葉で書くと全然違うように見え ますが、コンピュータ上ではそっくりです。上の2つの書き方はどちらもExcel では"=SUM(C1)"と書きます。これをどう読むかの違いなのです。
手続き的と宣言的の記述の一番の違いは、手続き的な記述には入っている「コ ンピュータ」という言葉が宣言的な記述には入っていないことです。手続き的 な記述に慣れてしまうと、宣言的な記述は不安に思えます。「このセルは合計 が入るセルだ」なんて書いても、どうやってそれが実現されるのか心配になっ てしまいます。それに対して「コンピュータがどうにかして勝手に実現してく れるのだから、実現方法は忘れてしまえ」というのが宣言的記述の教えです。
なぜ宣言的の方がよいかというと、実現方法を忘れてしまえるからです。もし 手続き的に「SUMは合計を計算する命令である」と理解してしまうと、Excelの 仕組みが気になって仕方なくなります。「合計はいつ計算されるのだろうか」 「どこかのセルの値を変えた時に合計が変になってしまうんじゃないか」とい う心配は、SUMを「命令」ととらえたから起きる心配事です。物事を宣言的に とらえればこんな心配は起きません。何がどうなろうとそのセルには合計が入っ ているのですから。例えセルの値を変えようとセルを追加しようと大丈夫です。 Excelがいつその命令を実行するかなんてことはどうでもいいことです。Excel が勝手にやってくれることを信頼しましょう。
手続き的な記述では、コンピュータはある命令を受けるとその命令を実行して おしまいです。それに対して宣言的な記述では、コンピュータはそれが正しく なるように常に動いています。そして世の中を見渡すと、多くのプログラムは 瞬間的に命令を実行しておしまいではなく、何かを待って常に動いています。 そういうプログラムを作るには宣言的な記述の方が向いています。
「プログラムのことは忘れよう」というのはこういうことです。宣言すればあ とは勝手にやってくれるのですから、どういう手順でどう動くかということは 気にしなくていいのです。
しかし、上で述べた「宣言的」というのはあまりにも絵空事で、一般のプログ ラミングには通用しないように思えます。ExcelでSUMが扱えるのはその通りだ が、それを一般にどう拡張するのかわからないというのももっともです。
自分がやろうとしている事に対してExcelのような「勝手にやってくれる存在」 があるでしょうか?ある場合もない場合もあります。これが一般に「フレーム ワーク」と呼ばれているものです。そして、フレームワーク上で数々の宣言を つくるもととなる単語がクラスライブラリです。Excelの例で言えば「セル」 や「合計」にあたります。
例えばウィンドウシステムでは、ウィンドウ上にテキストボックスやスクロー ルバーなどを配置します。これも「ウィンドウ上にテキストボックスを表示す る」ではなく「ウィンドウ上にテキストボックスがある」と解釈すべきです。 使う側は、マウスでクリックされた時にどうなるかやキーボード入力があった 時にどうなるかといった細かい動作は気にする必要はありません。テキストボッ クスにはユーザから入力されたテキストが(なぜだかわからないけど)入ってい るというだけの理解で十分です。Excelのセルと同じで、どのタイミングで入 るのだろうかと考えてはいけません。
もし自分がやろうとしている事に対してこのような既存のフレームワークがな い場合、残念ながら自分で作るしかありません。このような場合にも、フレー ムワークを使う側が「〜である」という文脈で記述でき、その動作はフレーム ワーク自体が勝手にやってくれるようにしなくてはなりません。
別の見方をすれば、フレームワークとクラスライブラリは「宣言の書き方」に あたります。これらの取り決めに従って宣言を書けば、あとは勝手にうまいこ とやってくれるのです。
フレームワーク化が進めば、プログラミングの出番はなくなります。(スクリ プトやCGIのない)普通のWebページではHTMLしか書かなくても立派に画像や動 画を表示したり画面を切り替えたりできます。オブジェクト指向の究極の目標 はここにあります。
「オブジェクト指向」が本当に意味するところがだんだんわかってきたでしょ うか?あるソフトウェアを作るのに、オブジェクト指向ではこういう考え方を します。「我々がこれから作るソフトウェアが完成した時の事を考えよう。こ れを使うと『もの』がどう動いてどうなるだろうか?」と。そしてそれを細部 まで言い表すことができたら、あとはコンピュータが勝手にそれを実現してく れます。こうして思い描いていた通りのソフトウェアができあがるのです。
「ソフトウェアの内部処理については考えずに、対象となる実世界について考 えよう」というのがオブジェクト指向です。実世界の現象を説明するために単 純化した仮説を立てることを「モデリング」といいます。オブジェクト指向は まず実世界のモデルを作りそれをコンピュータ内でシミュレートするすること によってソフトウェアを実現しようという試みなのです。
コンピュータが命令をしなくても勝手に動くことを「自律」と呼びます。人間 の命令に従うのではなく、コンピュータが自分で判断し自分で自分の行動を決 めるのです。
オブジェクト指向では「どう動かすべきか」ではなく「どう動くか」を考えま す。コンピュータは「人間が動かすもの」ではなく「勝手に動くもの」と考え ます。
また昔話になりますが、その昔、BASICという言語(今のVisual Basicとは別物) がありました。またLISPという言語もありました。これらの言語は、人間が逐 次入力した命令を実行することから「インタプリタ型」と呼ばれました。 こうした純粋な形でのインタプリタ型言語は現在ではほぼ絶滅していますが、 昔はコンピュータに命令を一つ一つ与えていって実行させることができました。
BASICの時代には、PRINT "バカ" などとやって、コンピュータに「バカ」と表 示させて遊んだものでした。BASICでは、コンピュータに「バカと表示しろ」 と命令するとコンピュータはその命令の通りに「バカ」と表示しました。それ が何だかうれしかったのです。そして、それをいちいち人間がやるのは面倒だ からその手順を記憶させて、さらにgoto文で好きな場所に飛ぶことができるよ うにして……と発展させてプログラムにしていました。
RUN(走れ)と入力すると、入力したプログラムが順次実行されました。そうし ながら、プログラマは自分がコンピュータに手でいちいち入力しているところ を想像していました。Breakキーを押すとそれは止まり、CONT(続けろ)を実行 すると続きが始まりました。
BASICでは、すべての操作はコンピュータへの命令でした。RUN(走れ)もCONT (続けろ)もLIST(コードを表示しろ)もそうです。そして、コンピュータは命令 を実行したら OK(終わりましたご主人様) と返事して、次の命令を待ちます。
これはMS-DOSでもUnixでもある意味同じです。プロンプト(=入力を促すもの) を出して、ご主人様からの命令をひたすら待ちます。そして命令されたことを して、またひたすら待ちます。これがコマンドラインの考え方です。
コマンドラインでは、コンピュータは常に部屋の隅に立っていて、ご主人様の 命令を待つ存在でした。ウィンドウシステムではこの考え方が変わりました。 ウィンドウシステムでは人間が何もしなくても常に何やら動いています。メー ルが来ると「メールが来ました」と知らせてくれますし、時間になると勝手に ウィルススキャンやハードディスクの掃除を始めます。コマンドラインがメイ ドだとすると、ウィンドウシステムは秘書に相当します。
コマンドラインとウィンドウシステムで、コンピュータの本質は何も変わって いません。単に人間側の見方が変わっただけです。
コマンドラインは「何もしないで命令を待つ」と書きましたが、これも本当に 何もしていないわけではありません。「待つ」という行動をしています。逆に、 ウィンドウシステムも実際は命令を待って行動しているだけです。ただ命令の 出所がご主人様だけではなく、「メールが来たからお知らせしろ」「時間が来 たからウィルススキャンをしろ」とあちこちから出されるだけです。
本質的な変化はコンピュータやプログラムではなくユーザ側にあります。コマ ンドラインでは、命令を出す人間はコンピュータの動作をすべて把握していま した。コンピュータは人間が命令したことしかしません。それに対して、ウィ ンドウシステムではユーザはコンピュータが裏で何をしているのかを把握して いません。コンピュータの本質は変化していないので、コンピュータは結局誰 かが命令したことしかできません。違って見えるのはだれがその命令を出した かです。コンピュータを使う人が出したものではなく、ソフトウェアを作った 人が出したものであるということです。
ユーザから見れば、「近頃のコンピュータは俺が命令しないことを勝手にやる」 と思っているでしょう。まるでコンピュータが自分でものを考えて自分勝手に 実行しているように見えるかもしれません。しかし実際はそれらはシステムの 作成者(例えばマイクロソフト)が命令したものなのです。
「命令もしないのに自分で勝手に実行する」ことを自律と呼びます。しかしこ れは本当にコンピュータが自分勝手に行動しているのではありません。コン ピュータは事前に受けた命令の通りに動いています。コンピュータがどんな命 令を受けているのかを知らないから、あたかも勝手に行動しているように見え るだけです。
プログラムはその都度ユーザから命令をもらうのではなく、あらかじめ命令書 の束をソフトウェアという形でもらいます。命令書には「○○の時は××せよ」 という条件と命令の組が事細かに書かれています。例えば「メールが来たらお 知らせしなさい」とか「スタートボタンが押されたらメニューを表示しなさい」 というようにです。このようにすれば、ユーザから命令をいちいち受けなくて もコンピュータは動作させられます。コンピュータに命令するには、コンピュー タにどのように命令したらよいかを知らなくてはなりません。今のコンピュー タはそんなことを知らなくても使えるようにできています。
コマンドラインとウィンドウシステムでは、ユーザの命令の意味合いも変わっ ています。コマンドラインで「del a.txt」と打つとファイルが削除されます。 これは直接「ファイルを削除しろ」と命令したことにあたります。これに対し て、ウィンドウシステムではファイルをゴミ箱に放り込むことでファイルが削 除されます。これは「ご主人様がファイルをゴミ箱に放り込んだよ。きっとい らないんだろうなぁ。消しちゃっていいかなぁ」とコンピュータが判断して (実際には「ファイルがゴミ箱に入れられたら、ご主人様の意図を察してファ イルを消去しなさい」という命令に基いて)、ファイルが消去されます。そし て、実際には消さないで、もしもの時のためにとっておきます。
今や、人間がコンピュータに示すのは「命令」ではなく「意図」です。命令と いうのは、それで何が起こるのかを命令する人自身が把握していなくてはなり ません。しかし今やほとんどのユーザはコンピュータが実際に何をしているの かを知りません。ファイルを「消す」とは実際にはどういうことなのかを(驚 くほど多くの)一般人は知りません。ただ「目ざわりなものがデスクトップか ら消えて便利」くらいに思っています。コマンドラインを使う人は、ファイル やディレクトリ、ドライブの概念を把握しています。ファイルを作るとどうな るか、ファイルを消すとどうなるかをわかって使っています。しかし今の人達 はそれをわかっていないまま使っています。だから「ファイルを消しちゃった んだけど何とかならない?」とか「ディスクがいっぱいになってますって言わ れたんだけど何でだろう?」というような質問がやってきます。
昔のコンピュータはユーザが動作に責任を持っていました。ユーザはコンピュー タを理解していて、自分がコンピュータに出した命令の結果がどうなってもそ れはユーザの責任でした。今ではそうではありません。ユーザがどんな無茶な 命令をしたとしても、ユーザが不満に思わないようにしなくてはなりません。
コンピュータは命令を理解し実行するシステムから、「こういう場合にはこう 動く」という行動規則を実行するシステムになりました。これを反応(リアク ティブ)システムと呼びます。命令を上から順に実行していくシステムから、 その場に応じて行動を変えるシステムに変わったのです。
コンピュータの実行単位はコマンドからイベントになりました。コマンドは人 間が呼び出しますが、イベントは状況に応じて勝手に実行されます。コマンド は順番に処理され、一つのコマンドが終わるまでは次のコマンドは実行されま せんが、イベントはそんな悠長なことは言っていられません。状況は刻々と変 わり、イベントはコンピュータがどんな状態かということとは無関係にやって きます。
コマンド処理は終わるまで待たなくてはなりませんでしたが、イベント処理は 終わるまで待つ必要はありません。イベントは出しさえすればあとは勝手に処 理されます。コマンド処理と違って実行の順番もあまり関係ありません。複数 のイベントが発生した時は、どのイベントからどう実行されるかはわかりませ ん。逆に言えば、それは気にしなくても勝手によいようにしてくれます。
コマンドは命令文ですが、イベントは何かが起きたことを示す普通の文です。 そして、命令にあたるものはすべて「要求」という形に変換されます。「ウィ ンドウを閉じろ」という命令は「ウィンドウを閉じるように要求された」とい う要求として扱われます。命令は即座に実行しますが、要求は都合によって拒 否したり後回しにしたりします。TPOに応じてそれを判断するのはコンピュー タ自身です。
今までは、システム全体の自律について考えてきました。ウィンドウシステム が全体として状況に反応するシステムだとして見てきました。自律の単位をシ ステム全体ではなく、オブジェクト単位にまで細かくした考え方が自律オブジェ クトです。
自律オブジェクトとは、オブジェクトそれぞれが自律しているということです。 オブジェクトそれぞれが状況に応じて勝手に動作をします。状況に応じてイベ ントが発生し、それがオブジェクトに通知されます。
自律オブジェクトの典型的なものがウィンドウシステムです。ウィンドウが閉 じられたとかマウスがクリックされたといった状況に対して、何をすべきかを 記述します。その中で他のウィンドウを閉じると、そのウィンドウにも「閉じ る」イベントが発生します。あるオブジェクトのイベント処理で別のオブジェ クトのイベントを発生させることを「メッセージパッシング」とも言います。
イベントやメッセージの考え方はこのように従来からある関数呼び出しの考え 方とは異なるものです。関数呼び出しは相手の実行が終了するまで待っていま すが、イベントやメッセージでは(概念的には)相手を待つことはしません。そ して、関数呼び出しでは呼び出しの前提条件や順番などが決められていますが、 イベントやメッセージはそれらは決まっていません。適当に投げればあとはそ のオブジェクトが処理してくれるようにしなくてはなりません。
オブジェクト指向の考え方では、オブジェクトは独立かつ自律して動作してい ます。それぞれのオブジェクトは周りの状況に応じて動作をします。オブジェ クトを使う側からすれば、そのオブジェクトがどんな風に動作するかというこ とは知る必要がありません。
これは以前例に挙げた「宣言的」の考え方とも通じるところがあります。オブ ジェクトを目的に応じて設定しておけば、後は何もしなくても勝手に必要な動 作をしてくれます。「ここのセルは合計である」と設定さえすれば、どこのセ ルがどう変わってもオブジェクトが勝手に処理してくれるのです。ユーザはい ちいち命令を出す必要がありません。
プログラムは一般に肥大化するとだんだんスパゲッティ化してきます。プログ ラムの複雑さは順列組み合わせ的に増えていきます。しかしオブジェクト指向 では、複雑さはオブジェクトの数に比例してしか増えていきません。オブジェ クトは自分のことは自分で処理しますから、相手がいくつあろうが、相手がど んな種類であろうが関係ありません。あらかじめどんな状況にあっても正しく 動作するように作られていますから、それをどう組み合わせても問題なく動作 するのです。
人間はすべてを把握する必要はありません。クラスライブラリの使い方を把握 すればいいだけです。好みの動作をするようにオブジェクトを設定し、オブジェ クト同士をつなぎ合わせるだけで、あとはすべて勝手に実行してくれるのです。
オブジェクト指向は「思想」あるいは「考え方」であり、具体的な方法やプロ グラムの書き方などではありません。だからよく誤解されます。「C++やJava を使うのがオブジェクト指向だ」と言う人は放っておくとしても [3] 、一見もっともらしい誤解はよく見受けられます。
オブジェクト指向に関する誤解のほとんどは、オブジェクト指向を「プログラ ミングが簡単になる便利な道具」として見ることに起因します。オブジェクト 指向はそんな安っぽいものではなくもっと深遠なものです。そして今まで何回 も繰り返したように、プログラミングが簡単になってもあまり意味はないので す。プログラミングというのはソフトウェアを作るにあたっては重要性の薄い 一工程に過ぎないのですから。
オブジェクト指向は「勉強」するものではありません。「理解」するものです。 あるいは「啓示を受ける」ものと言った方がいいかもしれません。 オブジェクト指向はよく宗教のようなものだと言われますが、その通りです [4] 。オブジェクト指向とは「ものの見方」です。ですから、やり方をうわべだけ 真似ても何の意味もありません。
オブジェクト指向の本では「人間は動物の一種である」とか「人間はご飯を食 べる」とか、およそプログラムとは関係のない説明ばかりが並んでいる。犬も 人間も動物であるということがWindowsのプログラムを組む上で何の関係があ るというのか。
その通り、プログラミングとはまったく関係がないのです。オブジェクト指向 というのは、どうプログラミングするか(how)ではなく、プログラムとは何か (what)にかかわる問題です。ソフトウェアとは何であり、プログラムを組むと いうのは結局どういう作業なのかです。
多くの場合、「ものを作る」という行為は「ものを理解する」という行為 より先に来ます。熱力学の研究の成果によって蒸気機関ができたのではなく、 逆に蒸気機関ができてから熱力学が研究されるようになったのです。人は難し い学問によって対象を理解しなくてもそれを作ることができます。ですから、 オブジェクト指向は「プログラムを作る」という行為に対しては全く関係があ りません。しかし理論をまったく知らないでカンと経験だけでものを作るよ り、対象を理解してからものを作った方が良いものができます。これがオブジェ クト指向を学ぶ意義です。
オブジェクト指向とは、「ソフトウェアとは何か」「概念とは何か」「動作と は何か」といった難しい問題について考えることです。ソフトウェアとは概念 であり知識であり考え方です。「ソフトウェアとは何か」という問いは「知識 とは何か」という問いでもあります。だから「人間はご飯を食べる」とか 「人間は動物の一種である」という例について考えることに意味があるのです。
オブジェクト指向は「哲学」です。ここで「哲学」と言ったのは俗に「経営哲 学」などという言葉で使われるような哲学ではなく、カントやデカルトがやっ たような [5] 本物の哲学のことです。そしてこうした哲学というのは教えられるものではな く、自分で考えて答えを見つけることにこそ意義があるものです。
「ソフトウェアっていったい何だろう?」と考えてみてください。そして、そ の問題に答えるという目的意識を持って本を読んでください。「役に立てよう」 という意識では方向を誤ります。
オブジェクト指向についてこのような説明をよく見かけます。この説明は本当 のオブジェクト指向の説明ではありません。構造化手法の説明です。オブジェクト指向とは、データと操作を一つのまとまり(カプセル)としてとら え、こうした部品の組合せでプログラムを表現することです。
構造化のことをオブジェクト指向と勘違いしている人がよくいます。それは 構造化手法が皆に理解される前にオブジェクト指向が流行り始めたからです。 そして構造化手法すら知らない人が多数群がり、オブジェクト指向言語で 構造化という概念に初めて触れたからです。C++やJavaなどのオブジェ クト指向言語は構造化手法の考え方の成果を取り入れて作られていますので、 構造化も非常にやりやすくなっています。そしてその「やりやすい部分」がオ ブジェクト指向だと勘違いされてしまったのです。
構造化手法とは「プログラムをわかりやすいまとまりに分割して管理する」と いう考え方のことです。ですから、「まとまり」「分割」という言葉が出た時 点でそれはオブジェクト指向ではなく構造化の考え方です。「部品化」 「モジュール化」「情報隠蔽」「再利用」という言葉も同様です。オブジェクト 指向とは「現実世界に目を向けよ」という考え方の事ですから「部品」とは 何の関係もありませんし、そもそも「プログラム」という言葉が出た時点でそ れはオブジェクト指向の説明として不適切です。
もちろん構造化は非常に重要な考え方であり、あなたがまだそれを知らないな ら是非学ぶべきです。もしあなたが「オブジェクトは部品である」と言われて 「なるほど、それは良さそうなアイデアだ」と思ったなら、あなたはやっと 「構造化手法」の入口に入ったということです。まず構造化手法を勉強し、き ちんと修得して卒業しましょう。オブジェクト指向はそれからでも遅くはあり ません。なぜなら構造化というのはそれだけプログラマにとって意味のあるこ とだからです。
と、ここでは否定的な話をしてしまいましたが、「部品化」という言葉に自律 のニュアンスを含めるなら、オブジェクト指向とは部品化であると言ってもい いでしょう。部品といっても歯車のような受動的な部品を思い浮かべてはいけ ません。モーターのような能動的な部品を思い浮かべるべきです。内部をよく 知らなくてもつなぎさえすれば動くという部品です。
よりニュアンスを引き出そうとするなら、「部品の組み合わせこそがプログラ ムである」と言うべきでしょう。ユーザはただつなげるだけで希望する動作を 実現できるようにするのがオブジェクト指向でいう「部品化」の意義です。
オブジェクト指向では「情報隠蔽」というキーワードがよく使われます。この 言葉を使うと、「オブジェクト指向では他人に見せる必要のない情報は隠蔽す るのだ」と思ってしまいます。
確かに間違いではありませんが、考え方が逆です。オブジェクト指向では、 「見せるべきでない情報を隠す」のではありません。基本的に情報はすべて隠 し、「見せないとどうしようもない情報だけを見せる」のです。「情報隠蔽」 ではなく「情報公開」をキーワードにすべきです。
使う側に立って見た時には、必要のない情報を欲しがらないようにしなくては いけません。そのオブジェクトがどう動いているかという情報は必要ありませ ん。あなたが何も知らなくても、ライブラリが勝手にいいように動作してくれ ます。あなたが知らなくてはならないのは、そのライブラリの使い方だけです。
「情報隠蔽」をキーワードにすると、たくさんメソッドを作ってからどれを公 開しようと考えがちです。これはやり方が逆です。外部からオブジェクトを設 定するのに必要なメソッドを用意し、それを公開して、それ以外はすべて非公 開にするようにします。
大事なのは、どう動作させるかということはひとまず置いといて、何を公開す ればいいのか、言い換えればどうユーザに使ってもらうかをまず考えることで す。そしてそれ以外のことはユーザには見せないようにします。情報はわざわ ざ見せない限り隠れているものです。だから考えるべきは「どう隠そうか」で はなく「どう見せようか」になるはずです。
オブジェクト指向は考え方であり、道具ではありません。ですから「オブジェ クト指向を使う」という言葉は(厳密には)間違いです。そして、カプセル化や 継承や多態性といったものも「使う」ものではありません。そこに「ある」も のなのです。
この違いはおわかりでしょうか。これは「発明」と「発見」の違いです。発明 というのは人間が何かを作ることです。それに対して発見というのはずっとそ こにあるものを人間が見つけることです。オブジェクト指向とは現実世界に目 を向けてそこにある構造や法則を見つけ出すことですから、それは発明する ものではなく発見するものです。
例えば、オブジェクトは作るものではなく見つけるものです。例えば「『ウィ ンドウ』をオブジェクトにすればプログラムがすっきり書ける」というのはオ ブジェクトを自分から作り出していること、すなわち発明していることにあた ります。これは考え方が逆です。「あっ、なるほど。『ウィンドウ』というも のがあるんだ。これを軸に考えればわかりやすい」というのが「オブジェクト を発見する」ことです。そして、オブジェクト指向の考え方は前者ではなく後 者です。
発明と発見の違いはかなり微妙です。ニュートンは引力を「発見」したといわ れていますが、別の考え方をすれば引力という概念を「発明」したとしたと言 えるかもしれません。しかし蒸気機関はそれらが発明される前には何もなかっ たのに対し、引力はニュートン以前からずっと存在しました [6] 。だから蒸気機関は発明であって引力は発見なのです。たとえ後の人が万有引 力の法則というものを星の運行を計算する道具としてしか使わなかったとして も、法則それ自体は道具ではありません。
オブジェクトも同様です。「ウィンドウ」というものもあなたが考え出したも のではなく、あなたが「ウィンドウをオブジェクトにしよう」と言い出す前か らずっと存在していたものです。だからこれは発見です。あなたは「コンピュー タの画面には枠で囲まれたいくつもの四角形が存在する」ということを発見し、 それを「ウィンドウ」と名付けたのです。同様に「ウィンドウの一種に、閉じ るまで他のウィンドウの操作ができなくなる特殊なウィンドウがある」という ことを見つけ、それを「ダイアログ」と名付けるのです。このように、継承も 作り出すものではなく見つけるものです。
オブジェクトを「作り出そう」と考える人はインチキ科学者に似ています。彼 らは自分が正しいと思い込んでいる事が証明されるように法則を「作り上げよ う」とします。法則というのは「作られる」ものではありません。対象を細か く観察し、あれこれ考えることによって「見えてくる」ものなのです。
オブジェクト指向のよくある失敗の一つに、何がなんでもオブジェクト指向を 適用しようとしてしまうことがあります。オブジェクト指向とは、「実世界の 現象を説明する」ための試みです。ですから、実世界の現象が簡単に説明でき てしまうようなソフトウェアはオブジェクト指向には向きません。
「オブジェクト指向には向かない」と言うより、「オブジェクト指向はごく一 部の助けにしかならない」と言った方がより正確でしょう。オブジェクト指向 を使うと、「対象がどうであるか」をコンピュータ内部に再現できます。しか し「どうすればいいか」はオブジェクト指向とは無関係です。この部分は従来 の方法で考えなくてはいけません。
オブジェクト指向がやりやすいのはデータベースやGUI、表示系などのソフト ウェアです。これらはまさに「対象がどうであるか」というのを記録したり見 せたりするソフトウェアです。それに対して、判断や思考、制御といったソフ トウェアはオブジェクト指向ではやりにくい対象です。例えば、将棋を指すソ フトを考えてみてください。オブジェクト指向によって、駒がどこにあり、そ れぞれがどういう動きをするかは表現することができます。しかし、それでど ういう手を打てばいいのかというのはわかりません。将棋とは何かというのを 知ることと、将棋でどんな手を打てばいいかということはまた違います。
一つの方法は、「思考」についてオブジェクト指向で考えてみることです。つ まり「将棋で次の一手を考える」というのはどんなことかを考えるのです。す ると「可能な手」とか「その手を打った時の展開」といったオブジェクトで表 現できるでしょう。これは将棋に限ったことではなく、囲碁でもチェスでもオ セロでも同じモデル化になります。つまり、「思考」について考えることは対 象について考えることとは別次元の話であり、対象に対して一段抽象的なレベ ルでものを考えることになります。
この落し穴に多くの人がはまります。「どうすればいいか」をオブジェクト指 向で考えるということは、「『どうすればいいか』をどう表現すればいいか」 という問題を考えるということです。そしてその答えは例えば「C言語の文法」 になってしまいます。答がわかったところでそれは表現のしかたがわかった だけで、どうすればいいかという根本問題は解決しないのです。
オブジェクト指向がGUIに向いているのは、判断は人間にまかせるからです。 自分で判断をするソフトではその判断部分はオブジェクト指向では書けませ ん。判断部分も無理にオブジェクト指向で書こうとしても出来てくるのは 「判断部分はどう書けばいいか」であって、判断部分そのものではありません。
オブジェクト指向とは「もの」について考えることです。how(どのように) ではなくwhat(何か)を考えることです。今まではプログラムを作る時にhow(ど のように動くか)だけしか考えずwhat(それは何か)をないがしろにしてきまし た。つまり、それが何かもわからずただ作ってみただけの状態です。水を沸騰 させて蒸気でものを動かす機械はできたけれどそれがなぜどういう原理で動く のかはわからない状態です。
「プログラムをどう作ればいいか?」ではなく「プログラムとは何か?」と自 分に問うてみてください。それは作るものではなく見えてくるものです。そし てそれを考えることこそがオブジェクト指向です。
さて、オブジェクトというのは実世界にあるモノや概念のことであって、オブ ジェクト指向というのは実世界のモデリングであるという話をしました。今ま でのソフトウェア開発手法では最小単位は「処理」であってそれを説明するに は「どんな処理をするものか」を書いたのに対して、オブジェクト指向では最 小単位は「オブジェクト」であり、それを説明するには「それは何か」を書か なくてはなりません。
では、オブジェクトの意味するところ、いわゆる「それは何か」を書くために は何を書けばいいのでしょうか。それについてここで話をしたいと思います。
さて、単刀直入にオブジェクトの3つの意味を挙げましょう。例えば「犬」と いうオブジェクトには次の3つの意味があります。
犬とはどんなものかを定義する
どれが犬かを定義する
犬にはどんなことができるかを定義する
まず、内包とは「犬とは何か」という問いの答です。辞書を引くと「食肉目イ ヌ科の哺乳類」とか「オオカミを家畜化した動物」といった事が書いてありま すが、これのことです。こういった説明を読むと、読んだ全員の頭の中に「犬」 という漠然としたイメージが浮かぶはずです。そしてそれが「犬」というもの なのです。
内包はどれだけ説明してもきちんと説明し切れない事に注意して下さい。そも そも「犬とは?」と聞かれて「イヌ科の動物」と答えるとは人をナメた辞書で はありますが、こうとしか言えないのも事実です。「オオカミを家畜化した」 とか「ペットとして広く飼われる」といくら説明を書いたところで、「犬とは 何か」の問いに答え切れるとは思えません。
内包を記述する時に犯しやすい間違いは、内包をできるだけ正確に記述しよう とすることです。内包は正確に記述できるものではないのであって、記述を読 んで各人の頭に同じものが浮かべばそれでいいのです。同様に記述にいちいち つっかかるのも間違いです。例えば「よく人に慣れる」という記述があったと して「うちのポチは飼い主にすら絶対に慣れないからあれは犬ではないのか」 と反論するのは間違いです。犬というものの大まかな性質を述べただけにすぎ ないのですから。
内包を記述するのは簡単なようで非常に難しい問題です。その対象が簡単なも のほど難しい事です。「犬とは何ですか?」という問いに的確に答えられる人 はほとんどいないはずです。ただ幸いなことに記述するのに難しい概念の多く は一言で言えば皆がわかる概念です。あまり深く首を突っこむのはやめましょ う。わかればそれでいいのです。
内包というのは概念であって漠然としているものです。内包は話をしている全 員に「あああれのことか」と同じイメージを持ってもらうためにあるものです。
「犬とは何か」というのが内包でした。それに対して「どれが犬か」という問 いの答が外延です。概念的には「うちのポチと隣のジョンとお向かいのダック ス君と……」とこの世界にあるすべての犬を列挙したものです。もちろん実際 にはこのような事はできません。ですから実際にはだれかが何かを持ってき て「これは犬ですか?」と質問した時にイエスかノーかを判断する基準となる ものを外延と呼びます。「ポチは犬」「ジョンは犬」「タマは犬じゃない」と いうように。世の中のすべての犬が列挙できなければ、せめてこの判断をする のに十分な条件を定めることが外延を定義することにあたります。
例えば「うちのアパートでは犬は飼ってはいけない」という規則があったとし ましょう。すると、ひねくれ者のおばさんが「犬とは何か」と執拗に聞いてき たとします。「うちのジョンが犬だという証拠はあるの?そもそも犬って 何?」と。この場合の「犬って何?」というのは内包ではなく外延を問われて いるのですから、「犬とは食肉目イヌ科の動物で……」と言うのは無駄です。 そうした知識は目の前のジョンが犬かどうかを判断する証拠にはならない のです。 こういう場合には例えば「四足で歩き、ワンワンと吠えてうるさく、そこら中 にフンをして回る動物」というように「この条件を満たせば犬だ」という条件 を挙げることになります。
もちろん、外延もすべてを述べつくすことはできません。規則には必ず例外が ありますから。だからどこかで妥協が必要です。例えば「うちのジョンは 足を怪我していて歩けないし、だからフンをして回ることもないし、ワンワン と吠えたこともないんです」と言われれば、それが犬であるかどうかはともか く、別にアパートで飼ってもいいかなぁと大家さんは判断するわけです。外延 を記述する時には、その適用範囲(ドメイン)を考えて、必要十分なだけの記述 にします。ここでは「犬」というのはアパートで飼ってもいいかどうかを判断 するために定義したものですから、極言すればアパートで飼っても問題ないも のは犬ではないと言っても困らないわけなのです。
まとめます。外延とは「どれが犬か」あるいは「これは犬か?」という問いに 答えるためのものです。外延のすべてを正確に述べることは実際にはできませ んから、適用範囲を限ってそれに十分な条件を記述します。
「犬」に対して「走る」とか「ワンワン吠える」とか「肉を食う」とか、その ものができる事を列挙するのが機能です。これもまた全部を列挙することはで きませんから、適用範囲を限って必要な機能を列挙することになります。
例えばペットショップに「番犬として犬が欲しい」と言えば、犬とは「人を察 知」して「知っている人かどうかを見分け」て「大きな声で吠える」ものです。 「愛玩用に欲しい」となれば「人に慣れ」「かわいくクンクンと鳴き」「見た 目も愛らしい」ものです。そしてその総体として「犬」はこれらすべての機能 を持ちます。ペットショップで「犬をください」と言えば「こいつはほとんど 吠えずにおとなしく、誰にでも慣れますよ」とか「こいつは耳が良く勇敢で速 く走ります」とかいろいろとアドバイスしてくれるでしょう。つまり、ペット ショップにおいては(そしてその他のほとんどの場面では)「犬とは何ぞや?」 というどうでもいい議論よりは「犬に何ができるか」の方が重要なのです。
たいていの場合「機能」というのはまっ先に問題になりますから、機能を列 挙するのはさほど苦労はしないでしょう。ただ、オブジェクトの説明として機 能しか書かないという例は多く見受けられます。オブジェクトの記述を書く時 は「内包」や「外延」と意識的に区別して書く必要があります。
オブジェクトにおいて本質的なのは「内包」、つまりオブジェクトとは何であ るかです。外延や機能はそれに比べれば副次的なものです。しかしプログラマ は往々にして「機能」を重要視したがります。これではオブジェクト指向の本 質は見えてきません。プログラムではなく実世界を考察するというのがオブジェ クト指向なのですから。
「内包」というものは正確に記述することができません。そしてそれが厳密性 を好むプログラマという人種には受け入れられないかもしれません。しかし、 本来は厳密性なんてどうでもいいのです。要は理解できるかどうかなのですか ら。
オブジェクトを正確に定義しようとすると外延による定義になってしまいます。 内包は厳密に定義することは不可能であり、また外延は厳密に定義するための ものなのですから、これは当然の帰結です。そしてその結果、外延による定義 が重要視されて内包による定義は忘れられてしまいます。時が経つにつれて定 義は形骸化し、文章の重箱の隅をつつくような論争が始まってしまいます。
何のためにオブジェクトの定義をするのかを忘れないようにして下さい。もの に名前をつけ、その名前と意味の対応付けを皆が共有するためのものです。 そして「意味」というのは「内包」です。
オブジェクト指向とはつまり機能とかプログラムとかはとりあえず忘れて実世 界についてを考えよう、という方法です。実世界で使われる概念を「オブジェ クト」としてきちんと定義して、それがどんなものかを明確にしようという考 え方です。いったん概念が明確になってしまえば、その間の関係や機能や動作 はすらすらと出てきます。オブジェクトは「機能のまとまり」ではありません。 「概念のまとまり」なのです。「機能」はとりあえず忘れよう、というのが合 言葉であることを忘れてはいけません。
オブジェクト指向に限らず、システムはシンプルイズベストです。問題を領域 に分け、その領域の中で必要かつ十分な定義をします。慣れてくると実世界を より精密にモデリングしようとたくさんのオブジェクトを含んだ図を書いてし まいがちですが、それが対象領域(ドメイン)にとって本当に必要なのかを取捨 選択しなければなりません。たくさんオブジェクトを定義して複雑なモデルを 作るより、少ないオブジェクトでシンプルな定義をする方がずっと有用なので す。
最後に、まだオブジェクト指向がうまくイメージできない人のために、一つ提 案をしましょう。
目的のものをいきなりプログラムコードで書いてしまわないで、まずは自分が 一番書きやすいと思う何かで一度書いてみましょう。それは図でも文章でも落 書きでも(はたまた別のプログラミング言語でも)何でもいいです。まあ普通の 人は図が一番わかりやすいと思います。
「何か」で書いてみたら、次にはその書いたものをそのままデータ構造にして、 どうやったらそのデータ構造を使って動作を実現するかを考えてみましょう。
大げさに言えば、目的のアプリケーションを一番記述しやすいようなプログラ ミング言語を自分で新しく作ってしまいましょう、ということです。
| [1] | 専門用語で書けばこういう事です。 |
| [2] | なお、これらの教えが今も意味を持っていると信じるのは古臭い考えです。 Javaでプログラムを勉強するような人に「GOTO文は使うな」と言っても 「GOTO文って何?」と聞かれるだけでしょう。知らないものを使っているわけ がありません。 |
| [3] | どうせ言うならSmalltalkやEiffelにしてほしいものです。 |
| [4] | 日本人はなぜか「宗教」という言葉を毛嫌いしますが、宗教というのは大切な ものです。オウム真理教や創価学会だけが宗教ではありません。神社へ初詣す るのも、合格祈願するのも、お守りを身につけるのもみな宗教です。そして本 当に宗教なのは、これらの行動のベースになっている「すべてのものに神様が 宿る」とか「神様に祈るといいことがある」という考え方です。つまり、宗教 というのは考え方なのです。 |
| [5] | あるいはちょっと前に話題になった「ソフィーの世界」で書かれているような。 |
| [6] | ここに深入りすると唯物論と観念論の話になってしまいます。ほら、オブジェ クト指向は哲学だと言った通りでしょう。私にはそこまで深入りして説明する 能力はないので、ここはさらっと聞き流してまともな哲学の解説書を読みましょ う。 |