2006年11月16日 16:55 [Edit]

オブジェクトは難しくない。難しいのはクラス

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

オブジェクト指向を正しく理解する: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


この記事へのトラックバックURL

この記事へのトラックバック
さすがにJavaやPHPはなかったけど、高級言語を先に学ぶというのは今にはじまったことじゃない。 304 Not Modified: プログラミング初心者はギークから学べるのかそんな私が学んできてずっと思っていたことは、私はC言語から学び、Java、PHPと進んできたが、今の人はいきな....
いきなりCの方がよっぽど難しい【404 Blog Not Found】at 2008年12月17日 12:34
PERL HACKS(日本語版) [英語版] うーん、さすがにそれはいいすぎでしょうか。 クロージャの概念をクラスとの対比でわかりやすく説明する。 - サンプルコードによる Perl 入門ここで気づいてほしいことは、クラスとクロージャは、実は同じものだということです。
perl - Class vs. Closure【404 Blog Not Found】at 2008年07月13日 03:25
その違いは微妙というにはあまりに大きいので、ここでおさらい。 駄文 - JavaScript と「クラス」と「コンストラクタ」と「プロトタイプ」って言葉の定義が難しいよなあ - IT戦記 JavaScript関数の実体は、Functionクラスのオブジェクトです。今回はFunctionクラスの機能...
タイプ・クラス・プロトタイプ - OOの語彙【404 Blog Not Found】at 2008年04月13日 06:16
Rubyist Magazine - ちょっと特異な特異メソッド入門 404 B...
Singleton Method (特異メソッド)【□△○制作日誌】at 2007年01月28日 12:33
オブジェクトっていつからこんなややこしいものになったのか。 sumim’s smalltalking-tos - オブジェクト指向言語として必須な要素とは何か? ケイ パーソナルコンピューティングに係わるものをメッセージングで表現。 ストラウストラップ 抽象データ型(この文...
Perl 5はCOPでOOOP【404 Blog Not Found】at 2007年01月26日 06:17
ASAHIネット(http://www.asahi-net.or.jp)のjouwa/salonからホットコーナー(http://www.asahi-net.or.jp/~ki4s-nkmr/ )に転載したものから。 --- http://blog.livedoor.jp/dankogai/archives/50689356.html オブジェクトは難しく
Rubyの特異メソッドとCLOSのeql specializer【ホットコーナーの舞台裏】at 2007年01月13日 00:45
Blogの更新の途中ですがお知らせです。 本blogの 404 Blog Not Found:オブジェクトは難しくない。難しいのはクラス 404 Blog Not Found:Typeとは俺のことかとClass言い がITPro Watcherにて連載中の「404 Title Not Found」の方にも転載されたのでお知らせい...
[ITPro Watcher]オブジェクト指向二題【404 Blog Not Found】at 2006年11月19日 09:07
実は、TypeもClassもその意図は同じである。 finalventの日記 - ぶくまより オブジェクト指向とかあと、関数型言語っていうか、そういうのがOOPとどういう関係にあるのか、どうもすっきりしない。関数で表現できるならクラスとか要らないのでは?というか、ま、このあた...
Typeとは俺のことかとClass言い【404 Blog Not Found】at 2006年11月17日 01:15
この記事へのコメント
いちいち批判コメントを書いてるヒマがあったら、
自分でもっと良い記事を書いて、提示してみせたらどうかね?

あげ足を取ったり、批判するだけなら簡単だよ。
Posted by 評論家たちへ at 2006年11月21日 11:13
ちなみにRubyのURI同士は足せます。そんなの定義次第。
Posted by 言葉遊びは飽き飽き at 2006年11月17日 12:32
もっと技術的な見解がないと説得力があらへんわ。
Posted by あいてぃーぷろ at 2006年11月17日 10:59
うーん、ややこしい。単純に鋳型がぶっ壊れたと考える方がアホの私にはわかりやすいっす・・・
でも確かに母ちゃんメタファーはAUTOLOADっぽい考え方ですね。
Posted by 初学者K at 2006年11月17日 05:09
> 自分の知らないことは母ちゃんにきくというわけである。

プロトタイプの意味的に考えると、母ちゃんに聞くというよりは、人間は「無意識に」典型的人間の行動をする。ということではないでしょうか。

人間のプロトタイプを殺したときは、「死体を典型的人間」と定義したということで、母ちゃんが死んだということではないと思います。
Posted by amachang at 2006年11月16日 20:02