投稿日:

オブジェクト指向が理解できない理由


書いてみたらタイトルと内容があまり一致しない感じで若干ツリ気味なのですが、シレっとそのままリリースしちゃいます。また、これもタイトルと裏腹で、特に良い内容の記事ではありません。

前の記事で紹介させていただいたスライドが、おかげさまで 36,000 ビューを超えるという状況で、はっきり申し上げて、浮かれております(すみません)。ただビュー数よりも何よりも嬉しかったのは、はてなブックマークの方に寄せられた皆さんからのコメントでした。

今現在で、1784 ものブックマークを頂いています。内容はどれも好意的なものばかりで「分かり易い」「納得できた」と言っていただけた声があったことは、このスライドを書き始めた当初に思っていた目的を達成できたのかな?と思ってとても嬉しく思っています。

§ JavaScript の分かり易い解説記事が見つからなかった

たぶん10ヶ月ほど前だったか…、Twitter のタイムラインで「この記事で JS の prototype が理解できそう!」ということである記事が紹介されました。ちょうどその頃、縁あって JavaScript の本を書き始めていた僕は「おぉ!参考になるかなー?」とリンクを辿ったのですが、その解説はクラスベース指向でプロトタイプベースを理解しようと試みたもので、少なくとも僕には難解で、ツイッターでその情報をシェアしていた方にも「この説明はちょっと的を外しているから読まない方が良いかも?」とお節介を言ってしまいます(ホントにお節介でごめんなさい)。「なら、もっと良い解説は無いものか?」と、他の記事を探してみましたが、なかなか良いなと思う記事はが見つかりません。正しい情報はもちろんたくさんありましたが、専門性が高過ぎたりするものや、prototype 属性からプロトタイプチェインを説明しようとするもので、これは図解すればするほどややこしくなるという問題があるので、簡潔なものは見つかりませんでした。…はてブのコメントにもありましたが「難解な JavaScript」と言われる所以を感じました。

ところが、僕のまわりである程度 JavaScript を理解した友人は「JavaScript をシンプルだ」と言います。僕も同感です。そこで、そのギャップを埋めたくて書き始めたのがこのスライドでした。Twitter のタイムラインで「読まない方が良いかも?」とお節介してしまった方に読んで頂いて、喜んで頂きたいという思いもありました。書き始めたのは良かったのですが、忙しさにかまけて、すぐに放置状態に…。ところが最近、「京都で JavaScript の勉強会を開催したい」「JS OOP の難しいところ悩んでる人多いのでそのあたりを…」というお誘いを頂いたので、急遽そのスライドを仕上げて、発表させて頂きました。…そういえばはてブコメントで「タイトルが最悪」とツッコミを頂きましたが、JS勉強会での発表だったもので、じゃっかん派手に募集できるようにツリ色はあったかも知れません。てへぺろでございます。

§ オブジェクト指向を理解できない理由

さて、この記事の本題です。

上述のように、JavaScript によるオブジェクト指向プログラミングのイディオムを理解する上で、幾つからあまり好ましく無い解説をネット上で見掛けましたが、なぜでしょうか?

そこには、「クラスの呪縛」があるような気がしてなりません。

僕が最初にオブジェクト指向を学んだのは、Java 言語でした(※1)。Java 1.2 の頃。「これからは Web だろう!」と、Java と PHP と、どちらを学ぶべきか真剣に悩んだ末に Java を選択しました(※2)。Java 言語はクラスベースのオブジェクト指向言語で、クラスやインターフェースの仕様はピュアなオブジェクト指向の香りがしてとても好きなのですが…、この Java 言語をはじめとする、クラスベースのオブジェクト指向を採用した多く言語の成功が、「クラス」という概念と、「オブジェクト指向」という概念を、あまりにも強烈に結び付けてしまったように思っています。

実際に、クラスベースの言語を学んだ方からは、JavaScript のプロトタイプベースのオブジェクト指向は「奇異」なもの、あるいは「複雑」なものに見えるかも知れません(※3)が、ここで言いたいのはそういう事ではなくて、「例え Java 言語であろうとも、クラスが主役だと勘違いすると、オブジェクト指向プログラミングの本質を見失う」という事です。…つまり、「オブジェクト指向が理解できない」に繋がる可能性がある、と思うのです。

オブジェクト指向プログラミングの本質は、やはり「オブジェクト」な筈です。クラスやインターフェースを初めとする型システムも、あるいは JavaScript のプロトタイプベースの仕組みも、どちらもオブジェクトを上手く扱う為の「テクニック」に過ぎません。それは、「ああ、こうやってインスタンスを作るのね」「なるほど。こうやって実装を再利用できるのか」という程度の手法の問題に過ぎません(※4)。

僕は、オブジェクト指向プログラミングで大切なのは、「オブジェクトがそれぞれの役務を持ってその義務を果たすこと」に集約されるものと考えています。以前投稿した「オブジェクト指向プログラミングを理解する為の4つのポイント」には次のように書きました。

オブジェクトを役割分担するメリットは、そのまま「オブジェクト指向プログラミングのメリット」と言えます。オブジェクトが役割毎に分けられると、それぞれのオブジェクトは小さく、そして単純になります。役割の少ない、小さなオブジェクトは、簡潔で見通しが良くなります。シンプルなコードは変更も簡単で保守もしやすいです。また、単純なロジックだけが含まれることで、バグが混入しにくくなります。プログラマは小さくて閉じた世界だけで考えることができるので、自信をもって「論理的に正しい」と言えるコードを書きやすくなり、不安も減るでしょう。また、十分に設計が上手いと、再利用性が高いオブジェクトを作ることもできます。このように、オブジェクトに明確な役割を持たせることで、様々な恩恵を得ることが出来るようになります。これが、オブジェクト指向プログラミングの最も重要な概念です。

色々な解釈があると思うので、この理解が唯一、とはもちろん言いません。ただ、もし「オブジェクト指向を上手く使えて無いなぁー」という感覚がある方がいらっしゃったら、クラスではなく、よりオブジェクトをより意識した設計を意識してみると、何か発見があるかも知れません(※5)。

§ 終わりに

例のスライドはかなり好評を頂きましたが、JavaScript でのオブジェクト指向プログラミングについて必要な知識や基礎理解を紹介したものに過ぎず、オブジェクト指向プログラミング自体については、1つも言及していません。実は、ここにも良い解説が見当たらないなーと思っています。ただ、こちらはちゃんとしっくり理解するまでにはちょっと長い道程があるので、解説記事で片付くものは無いよね、とも思っています。

しかし、先日良い記事を教えて頂きました。

オブジェクト指向もまさに「書いて覚える」ものだと思います。この原則に立って、その「書く」の最初のとっかかりと、その時に感じて欲しいものを示すようなチュートリアルがあればなーと最近は思っています。どうだろう? そんなのは書けるのでしょうかね?誰か書いてください。

今のところふわっと思っているのは「インターフェース」について注目することです。いわゆるクラスベース言語の「インターフェース」ではありません。メソッドのシグネチャとか、そういうところで、提供側ではなくてオブジェクトのユーザー視点で考えるのが良いんでないかなーと思っているのですが、さて、このあたりの勉強なんて全くしたことないので、ぜんぜん外してたらすみません。ふわっとですよ。ふわっと思っているだけなので。 (*’-‘*)

 

この記事はここまでにさせて頂きます。
ありがとうございました。

 

 

  • (※1)Java 言語について:Java 言語を学ぶにあたって分厚い真っ黒い本(ブラックブック!)を1冊買って、最初っから最後まで2回ほど繰り返して読みました。当然ながらクラスやインターフェースの説明があり多態性の説明があります。なるほど、クラスとはこういうものか。なるほど、インターフェースとはそういうものか。2回ぐらい読むと分かったような気になります(もちろん、教科書的な理解でプログラムが書けるものではなく、概念として心にちゃんと収まったのはそれから何年も先でしたが)。そのブラックブックで僕が感動したのは、クラスやオブジェクトの解説ではなく、Collection ワークでした。Collection インターフェースが、それを継承した具象クラスの中でその利用目的に合うように実装されるのですが、ここに多態性やカプセル化の大きな「パワー」と「利益」を感じたわけです。これはすごいなーと。それは素晴らしい感動で、僕が普段からプログラミングに求めてしまう芸術性を、最初に感じさせてもらったプロダクトだったと思います。
  • (※2)3年後にはPHPにしておけば良かったと悔やみ、今はJavaを選択して良かったと思っています。
  • (※3)クラスがある方が宣言的に見えて分かり易い、という話はこの話の本質とはズレるので横においておかせてください。
  • (※4)ES6 で class というキーワードが導入されることも同様です。これがプロトタイプ継承のシンタックスシュガーである、という以前の問題です。
  • (※5)そんなこと言う僕も、まだまだぜんぜんで、悩み中です。いつも失敗するのがオブジェクトの粒度や抽象化対象のミスです。OOPはやはり難しいなーといつまでも思っています。

コメントを残す