大人だからオブジェクトは難しくなる。子供にとっては実はオブジェクトは自然で自明で簡単だ。

オブジェクト指向を正しく理解する:ITpro
オブジェクト指向はしばしば,とっつきづらく難しい技術と言われます。その理由の一つには,対象とする分野が広く,それぞれに深みがあることが挙げられます。しかし,それ以上にこの技術を難しくしている落とし穴とも言うべき原因が二つあると筆者は考えています。それは比喩を乱用する説明の仕方の問題と,「もの中心」を意味するコンセプト自体の問題です。

事実、オブジェクト指向というのは最初は子供向けだったのだ。

このことを、現在「オブジェクトとはなんぞや」という大人たちは忘れてしまっている。

それで、オブジェクトとは何か、といえば、「自分が何が出来るのかを知っているデータ」ということになる。それ以上でもそれ以下でもない。犬は吠えることはできても話すことは出来ない。URLからホスト名やパスを取り出すことは出来ても、URLどおしを足すことは出来ない。犬が哺乳類で、URLが文字列でというのはその後でかまわない。

人間の学習においては、必ず具象から入ってそれを抽象していく。慣れてくれば抽象を組み合わせて具象化したり、抽象化したものをそのままさらに抽象化したりするが、まず具象があるというのは変わらない。

ところが、電脳においては、すでに抽象化されたものがそこにあって、いきなりそこから入らねばならない。これこそが、本来簡単なオブジェクト指向を難しくしている理由なのである。

それでは、なぜ電脳においては抽象化が先になされていなければならなかったのか?そうでもしなければ、使い物にならなかったからだ。電脳は今でも根源的に0と1しか扱えない。しかも我々が普通に使っている電脳では、0と1を一個づつ扱うことも出来ず、最低でも8つまとめて扱う必要があったりする(これがbyte)。

だから、電脳における最初の仕事は、0と1から具象を作り出すことになる。0と1を32個まとめて「整数」をこさえたり、8つの0と1を文字に対応させ、それを並べて「文字列」をこさえたりといった作業だ。

こうした「再具象化」されたものを集めて、はじめて「人間向き」のオブジェクトが出来上がる。そして一旦出来上がったオブジェクトであれば、粘土や折紙を使うがごとく、それを「使う」ことにある。

オブジェクト指向の本質は、理解することではなく使うことにある。だから普及したオブジェクト環境というのは、いずれも「すぐに使えるオブジェクト」が用意されているし、「使える」ようになるまではなかなか普及しない。VBのコントロール、JavaScriptのブラウザー、そしてPerlのCPAN....Rubyが最近普及してきたのも、Rubyが優れているというよりRubyで使えるオブジェクトが充実してきたことが大きい。「まずオブジェクト指向ありき」なのではない。「まずオブジェクトありき」なのである。

しかし使いやすいものを作るのは難しい。オブジェクト指向であれ何であれ。ある製品を作るときに、それをいくつの部品から組み立てるのかというのはいつの時代でも難しい問題だ。部品を多くすれば柔軟性が増す代わりに組み立てが難しくなる。部品を減らせば簡単に組み上がるが柔軟性が損なわれる。

設計者の、腕のみせどころだ。

ところで、多くのオブジェクト指向言語においては、オブジェクトの実装はクラスという概念においてなされる。先ほどオブジェクトとは自分が何が出来るのかを知っているデータと言ったが、実はクラスベースのオブジェクト指向言語においては、何が出来るのかを知っているのはオブジェクトそのものではなくクラスである。そしてなぜそういう設計になっているかといえば、その方が効率的だからである。

もしクラスなしでオブジェクトを実装しようとすると、オブジェクト自身がメソッドを持っている必要がある。オブジェクトが100個あったら、メソッドのために必要なメモリーは一個の場合の100倍必要だ。「人」オブジェクトも「犬」オブジェクトも、世の「実存オブジェクト」もこの点においては変わらない。

ところが、電脳の世界ではそれらをクラスという形でまとめられるのだ。オブジェクトは自分が何クラスに属するかだけ知っていればいい。メソッドが来たら、自分自身ではなく自分の所属するクラスに尋ねればいい。これならオブジェクトが100個あろうが100万個あろうが、メソッドの実装は一カ所でいい。

しかし、こうなるとクラスの設計は重大だ。そのクラスに属するオブジェクトに必要なことは、すべてそのクラスが知っていなければならない。101個目のオブジェクトしか必要としないメソッドでも、そのオブジェクトが必要ならクラスはそれを知っていなければならない。そのためにクラスを作り替えるか、それともそのオブジェクト用に別のクラスを用意するか....

JavaScriptとRubyは、それぞれPrototypeとSingleton Methodというやり方でこの問題を止揚している。

JavaScriptの場合、そもそもクラスというのは存在せず、オブジェクトしか存在しないが、クラスの役割を親オブジェクトにやらせることで「オブジェクト100倍でメソッド用のメモリー100倍」問題を解決している。自分の知らないことは母ちゃんにきくというわけである。だから母ちゃんがぐれたり死んだりするとまずいことになるが、一家、というか世界の寿命はそのページを開いて閉じるまでだからこれでも充分間に合う。母ちゃんがぼけるとどうなるかという例は、以前404 Blog Not Found:javascript - Prototypal Object Modelの落とし穴で論考したのでそちらを参照されたし。

これに対し、RubyのSingleton Methodというのは、あくまでクラスをベースとしつつ、特定のオブジェクトにのみ必要なメソッドを追加できるようにした仕組みである。「知っていることは自分で、知らないことはクラスで」というわけである。実に自然であり、Simon CozensがAdvanced PerlでRubyを絶賛しているのもむべなるかなである。

しかし、「オブジェクトとは自分が何を出来るのか知っているデータである」ということを知っていれば、これとて他でも実装できてしまうのである。Simon自身Class::SingletonMethodでそれがPerlでも可能であることを示したし、私も404 Blog Not Found:perl - Object::PrototypeでPOMを実装で別のやり方でもそれが可能であることを示した。

そして、一旦こうしたノウハウがクラスとして確立されれば、あとの人はこれを「使う」だけで済むようになる。これこそが、オブジェクト指向の醍醐味なのである。

こういったことを体感するのに、C++やJavaといった「硬い」オブジェクト指向言語というのは実はそれほど向いていない。クラスの作り方が事実上ひととおりしかなく、そしてなによりクラスやオブジェクトのありようまで言語内で変えることが難しいからだ。この点で一番柔軟なのは実はPerl 5だが、柔軟すぎてオブジェクトを「使う」際にコストがかかってるように思う。オブジェクトは作る機会より使う機会の方がはるかに多いので、->だけだとしてもこれはばかにならない。Perl 6が求められる所以でもある。

実際「オブジェクト指向が難しい」という人は、LLの世界ではあまり聞かない。聞いたとしても、よく話を聞いてみると、それがオブジェクトだと知らずに使ってたりする。オブジェクトを使うのはあまりに自然なので空気になってしまっているのである。

だから、私としてはこれだけは言いたい。犬でオブジェクト指向を語るのに飽きたなら、もうJavaだけでオブジェクト指向を語るのもやめませんか、と。

Dan the Whatever Oriented Person


編集部より:今回のエントリは,編集部の 要望により小飼弾氏のブログ404 Blog Not Foundから転載させていただきました。 本連載に関するコメントおよびTrackbackは、こちらでも受け付けております。