オブジェクト指向とは
「オブジェクト」とは何かという話をした後にいよいよオブジェクト指向とは 何かの話に移りたいと思います。オブジェクト指向とは要するに今まで述べた ようなオブジェクトを中心に考えていこうというだけの事に他なりません。そ してこれだけを言うと「なんだ、当たり前のことじゃないか。なぜ今さらこん な事を言うんだ?」と疑問に思うかもしれません。だからまず経緯として構造 化手法について話をしましょう。
構造化手法
ソフトウェア開発の分野で、「オブジェクト指向」の前によく言われていたの が「構造化手法」です。構造化手法のスローガンを一言で言えば「意味のある 単位にまとめよう」というものです。関数としてまとめ、構造体としてまとめ、 そしてライブラリとしてまとめます。そうすることによってプログラムがより わかりやすく書きやすくなりますというのが「構造化」の教えです。
構造化手法は一つの意識改革でした。それまでプログラムというのは「コンピュー タを動かすためのもの」であり、動きさえすれば何でもよかったのです。そ こに「人間がプログラムを見た時の見易さも考えよう」と言い出したのです。 そしてそのためにプログラムを関数という「部品」に分割し、それぞれについ てさらに詳しく考えていくことを提唱したのです。
構造化手法の考え方は今では当たり前のように受け入れられています。わかり やすいような関数の分割の仕方を考える事や、関数の集まりであるモジュール の分け方を考える事はだれでもやっている事でしょう。モジュールの構造図や データフロー図まで書いたことがある人は少ないかもしれませんが、やってい る事は同じ事です。
構造化手法が当たり前になった今、構造化手法とは何かを認識するにはそんな もののなかった昔に一度戻ってみる必要があります。それは、Basic(Visual Basicではない)やCOBOLやFORTRAN(これも今のものではなくできた当時のもの)、 あるいはアセンブラでプログラムを組んでみることです。これらの言語で行番 号の管理やGOTO文の嵐に出くわせば、今の言語がどのくらいありがたいかがわ かるはずです。「GOTO文は悪」とか「フローチャートを書け」とか「コメント をつけよ」という教えもその意味がわかるはずです。 [1]
仕様の増大からオブジェクト指向へ
構造化の考え方は「処理を部品に分割する」というやり方でした。どういうプ ログラムを作りたいかがまずあって、それを実現するにはどうすればいいかを 考えていたのです。しかしプログラムの規模が大きくなるにつれて別の問題が 生じてきました。「どういうプログラムを作りたいのかがよくわからない」と いう問題です。処理を部品に分割しようにも、そもそも処理自体があいまいに なってきてしまったのです。
これを解決する手段として、「内部処理(プログラム)はとりあえず忘れて、外 から見える事象についてだけを考える」という方法が提唱されました。プログ ラムではなく実世界を対象にして「どう処理するか」ではなく「どういう処理 をさせたいのか」だけを考えようというのです。研究対象がプログラムではな く実世界なので、関数とか構造体の代わりにオブジェクトという概念を導入し ました。
今までの考え方では、プログラムにどういう処理をさせたいのかということか ら分析が始まりました。例えば薬を管理するには「買ってきた薬を登録する」 とか「薬瓶を棚にしまう」とか「薬瓶から薬を取り出す」といったような「処 理」がまずあって、これらの処理を実現するのにどう関数に分割するかを考え るという順序でした。しかしオブジェクト指向ではとりあえず管理ソフトのこ とは忘れて、管理対象である薬と薬瓶について考えます。薬とはどういうもの で薬瓶とはどういうものか、そして我々はそれをどう扱うのかについて考えま す。構造化手法が内部からの視点であるのに対してオブジェクト指向は外部の 視点であると言えるでしょう。
宣言的記述
今まで「プログラムのことは忘れましょう」と述べてきましたが、「俺は作り たいのはプログラムで、それ以外の何物でもないんだ」と思う方もおられるで しょう。オブジェクト指向では、従来の「プログラム中心」の考え方そのもの を改める必要があります。ここではそれを「手続き的」と呼びます。
そもそも「プログラム」とは何でしょう。ある見方で言えばこれは「コンピュー タに対する命令」です。例えば表計算ソフトである列の合計を計算したいとし ます。これは人間がコンピュータに「列1の合計を計算してこのセルに値を入 れろ」と命令するという図式です。これを「手続き的」と形容します。
それに対して別の考え方があります。「このセルは列1の合計が入るセルであ る」と定義するという図式です。これは命令ではありません。これを「宣言的」 と形容します。「手続き的」と「宣言的」は言葉で書くと全然違うように見え ますが、コンピュータ上ではそっくりです。上の2つの書き方はどちらもExcel では"=SUM(C1)"と書きます。これをどう読むかの違いなのです。
手続き的と宣言的の記述の一番の違いは、手続き的な記述には入っている「コ ンピュータ」という言葉が宣言的な記述には入っていないことです。手続き的 な記述に慣れてしまうと、宣言的な記述は不安に思えます。「このセルは合計 が入るセルだ」なんて書いても、どうやってそれが実現されるのか心配になっ てしまいます。それに対して「コンピュータがどうにかして勝手に実現してく れるのだから、実現方法は忘れてしまえ」というのが宣言的記述の教えです。
なぜ宣言的の方がよいかというと、実現方法を忘れてしまえるからです。もし 手続き的に「SUMは合計を計算する命令である」と理解してしまうと、Excelの 仕組みが気になって仕方なくなります。「合計はいつ計算されるのだろうか」 「どこかのセルの値を変えた時に合計が変になってしまうんじゃないか」とい う心配は、SUMを「命令」ととらえたから起きる心配事です。物事を宣言的に とらえればこんな心配は起きません。何がどうなろうとそのセルには合計が入っ ているのですから。例えセルの値を変えようとセルを追加しようと大丈夫です。 Excelがいつその命令を実行するかなんてことはどうでもいいことです。Excel が勝手にやってくれることを信頼しましょう。
手続き的な記述では、コンピュータはある命令を受けるとその命令を実行して おしまいです。それに対して宣言的な記述では、コンピュータはそれが正しく なるように常に動いています。そして世の中を見渡すと、多くのプログラムは 瞬間的に命令を実行しておしまいではなく、何かを待って常に動いています。 そういうプログラムを作るには宣言的な記述の方が向いています。
「プログラムのことは忘れよう」というのはこういうことです。宣言すればあ とは勝手にやってくれるのですから、どういう手順でどう動くかということは 気にしなくていいのです。
クラスライブラリとフレームワーク
しかし、上で述べた「宣言的」というのはあまりにも絵空事で、一般のプログ ラミングには通用しないように思えます。ExcelでSUMが扱えるのはその通りだ が、それを一般にどう拡張するのかわからないというのももっともです。
自分がやろうとしている事に対してExcelのような「勝手にやってくれる存在」 があるでしょうか?ある場合もない場合もあります。これが一般に「フレーム ワーク」と呼ばれているものです。そして、フレームワーク上で数々の宣言を つくるもととなる単語がクラスライブラリです。Excelの例で言えば「セル」 や「合計」にあたります。
例えばウィンドウシステムでは、ウィンドウ上にテキストボックスやスクロー ルバーなどを配置します。これも「ウィンドウ上にテキストボックスを表示す る」ではなく「ウィンドウ上にテキストボックスがある」と解釈すべきです。 使う側は、マウスでクリックされた時にどうなるかやキーボード入力があった 時にどうなるかといった細かい動作は気にする必要はありません。テキストボッ クスにはユーザから入力されたテキストが(なぜだかわからないけど)入ってい るというだけの理解で十分です。Excelのセルと同じで、どのタイミングで入 るのだろうかと考えてはいけません。
もし自分がやろうとしている事に対してこのような既存のフレームワークがな い場合、残念ながら自分で作るしかありません。このような場合にも、フレー ムワークを使う側が「〜である」という文脈で記述でき、その動作はフレーム ワーク自体が勝手にやってくれるようにしなくてはなりません。
別の見方をすれば、フレームワークとクラスライブラリは「宣言の書き方」に あたります。これらの取り決めに従って宣言を書けば、あとは勝手にうまいこ とやってくれるのです。
フレームワーク化が進めば、プログラミングの出番はなくなります。(スクリ プトやCGIのない)普通のWebページではHTMLしか書かなくても立派に画像や動 画を表示したり画面を切り替えたりできます。オブジェクト指向の究極の目標 はここにあります。
オブジェクト指向とは実世界のモデリングである
「オブジェクト指向」が本当に意味するところがだんだんわかってきたでしょ うか?あるソフトウェアを作るのに、オブジェクト指向ではこういう考え方を します。「我々がこれから作るソフトウェアが完成した時の事を考えよう。こ れを使うと『もの』がどう動いてどうなるだろうか?」と。そしてそれを細部 まで言い表すことができたら、あとはコンピュータが勝手にそれを実現してく れます。こうして思い描いていた通りのソフトウェアができあがるのです。
「ソフトウェアの内部処理については考えずに、対象となる実世界について考 えよう」というのがオブジェクト指向です。実世界の現象を説明するために単 純化した仮説を立てることを「モデリング」といいます。オブジェクト指向は まず実世界のモデルを作りそれをコンピュータ内でシミュレートするすること によってソフトウェアを実現しようという試みなのです。
なお、これらの教えが今も意味を持っていると信じるのは古臭い考えです。Javaでプログラムを勉強するような人に「GOTO文は使うな」と言っても「GOTO文って何?」と聞かれるだけでしょう。知らないものを使っているわけがありません。 ↩︎