某所でオブジェクト指向についていろいろ書いたのでまとめておく。
問題意識としては初学者がなにかというと「オブジェクト指向できるようになりたい」のようなことを言うけどそこまでの優先順位でがんばるものではないんでは、というところです。
まず前提として、オブジェクト指向は1980-2000年くらいに流行って発達したものの、それ以降は時代にあわせた進歩はしていない20年以上前の技術ってのがあります。
そのころは今だとCPUのキャッシュにも満たないようなメモリをやりくりしてプログラムを書く必要があったので、オブジェクト指向はメモリ上のデータをコピーすることなくうまく使いまわせるようなプログラム技術になっています。
そしてオブジェクト指向にはそこから目だった更新はなく、タイトルに書いたように、カメラがやっとついたくらいのガラケーのような古い技術という感じがします。
オブジェクト指向について、アプリケーションを組むときに考えるべき必須技術みたいな書き方がしてあると「いまはスマホの時代やで」に近い、もっと現代的な考え方ができるようにしようよという気持ちになります。
じゃあ現代的な考え方ってなんなのとなるけど、それはどちらかというと関数型になるんじゃないでしょうか。
関数型は実装としてはメモリをふんだんに使う仕組みになるので、昔は実用には厳しかったものの、いまでは8GBでも貧弱と言われるくらい余裕があるので、当たり前に使えるようになっています。
オブジェクト指向最盛期につくられたC++もJavaも、いまではラムダ式のような関数的構文をとりいれて、オブジェクト指向でプログラムを書くときの指針でもあったデザインパターンは、多くが「それラムダで素直にかけるよ」になっています。
あと、オブジェクト指向がどういうプログラミング技術だったのかを考えると「いかに状態をオブジェクトに閉じ込めて扱いやすくするか」という技術だったと言えます。
一方で関数型は「いかに状態を追い出して考えなくていいようにするか」という技術と言うこともできます。
オブジェクトと関数は視点の問題でもあって、オブジェクトで関数を実現することもできるし、関数でオブジェクトを実現することもできます。Javaのラムダ式はオブジェクトとして実現されていますね。
そして、いまの主流はWebアプリケーションで、サーバーサイドを書く場合には「ステートレス」つまり状態をもたないように書くことが基本になっています。状態はデータベースなどのストレージに格納されるようになってますね。そのようにアプリケーションに状態をもたないのであれば、状態を扱いやすくする必要はないので、関数型のほうが向いているということになります。
また、オブジェクト指向が発展した1980-2000年というのは、ユーザー端末にウィンドウシステムが取り入れられるようになった時期です。ユーザーインタフェースには、テキストボックスやボタンなどの部品の状態をうまく扱うことが求められるので、オブジェクト指向が相性がよく、オブジェクト指向とGUIは共に発展してきた面があります。
しかしいま、ユーザー端末もWebブラウザベースで作ることが基本になり、ブラウザの中では状態はDOMとしてすでに閉じ込められているので、アプリケーションとしてオブジェクトの状態を考える必要性は薄くなってきています。
さて、こう考えると、「なぜオブジェクト指向がわからないのか」という初心者がまどわされがちの疑問についても答えが見えてくると思います。
もしWebアプリケーションのサーバサイドを書きながら「なぜオブジェクト指向がわからないのか」と思っているなら、「あなたの書いてるコードにはオブジェクト指向が不要だからです」が答えになります。サーバーサイドにはオブジェクト指向があまり向いていないので、いかにうまくオブジェクト指向で書こうとしても「しっくりこない」「わからない」ということになっていくと思います。
オブジェクト指向がむいているはずであったGUIにしても、いまどきのGUIフレームワークであればあまりオブジェクト指向を考える必要なく、関数をイベントに割り当てていくだけでアプリケーションを組むことができるようになっています。そのため、GUIアプリケーションでさえ、「オブジェクト指向がしっくりこない」になりがちです。
JavaのSwingを使ってUIを作る場合であれば、オブジェクト指向だなーという感じになりますが、より新しいJavaFXを使ってUIを作るときは あまりオブジェクト指向感はありません。(個人の感想です)
こういうことを書くと「いやいやモジュール化や開放/閉鎖原則のような、プログラムを組むうえでの大事な考え方がオブジェクト指向にはあるじゃないか」というツッコミもあるかもしれませんが、そういったソフトウェア構築の大事な原則というのは、オブジェクト指向がうまく取り込んだだけであって、オブジェクト指向が必須というわけではありません。
プログラムの構成単位がオブジェクトなのであれば、それらの原則を適用するためにオブジェクト指向が必要になりますが、いまどきの言語は関数が独立して扱えるようになっているので、オブジェクト指向にこだわる必要はなくなっています。
もちろん、いまのスマホが昔のガラケーがあったからこそ成り立っているように、いまのソフトウェア技術もオブジェクト指向があったからこそ成り立っているという面もあります。
オブジェクト指向全盛の時代につくられたJavaであれば、オブジェクト指向をわかっていれば使いやすいところもたくさんあります。
アプリケーション全体としてオブジェクト指向で考えることが向かない場合でも、部分的にはオブジェクト指向的に考えたほうがすんなりいくこともあります。
その意味ではオブジェクト指向は習得していると有利な考え方ではありますが、プログラムを組むためにオブジェクト指向は理解するべきというほどの必然性はなくなっています。
いまでは各言語に実装されているオブジェクト指向的機能を使えれば十分で、「オブジェクト指向を理解する」のように肩ひじはって考えるのではなくて、Javaであればclassの継承やinterfaceの使い方を理解するというように、目の前の機能に向き合えば十分な気もします。それらにしてもWebアプリケーションであれば自分で理解して書く機会はそこまで多くないので、初心者のひとが「オブジェクト指向がわかりません」と言ってるのを見ると、じゃあそれはほっといて まずはアプリケーション書こうぜって気持ちになります。
また、いろいろな言語にオブジェクト指向的機能が取り入れられてますが、それぞれの言語によって違いがあり位置づけも違うため「オブジェクト指向」とひとまとめに扱えるものではなくなっています。その意味でも、目の前の言語機能に向き合うことのほうが大事になってると思います。
まとまらないので、ここまで。
そして最後に取り上げるのがこんな本かという感じですが、この他の著者のかたがオブジェクト指向について書いている中で「オブジェクト指向はまぼろしか?」という記事で、オブジェクト指向の歴史的な流れから、どのようにオブジェクト指向は使われなくなったかということを書いています。
よくみると定期的にオブジェクト指向について書いてるな。これらは7年前のもの。
オブジェクト指向は禁止するべき - きしだのHatena
オブジェクト指向について - きしだのHatena
1/22追記
この「オブジェクト指向について」でも書いてますが、基本的にぼくの「オブジェクト指向」はランボーのOMTに従っています。世の中でよく言われている「オブジェクト指向」もOMTを源流のひとつとして熟成され ただよってるものだと思います。
そこでランボーはオブジェクト指向とは「データ構造と振る舞いが一体となったオブジェクトの集まりとしてソフトウェアを組織化すること」と呼んでます。
個人的には、ソフトウェアの全体、もしくはその機能の全体をオブジェクトの集まりとして組織化するのであればオブジェクト指向の勉強は必要だと思いますが、その機会は少なくなっているし、単にデータと操作をまとめて扱いやすくするとかデータの分類を継承によるサブクラス化で行う程度であれば言語機能の理解で充分ではないか、と思います。
クラスライブラリやフレームワークをうまく使いたいという話であれば、それを使うための言語機能を勉強することを「オブジェクト指向」というのは、おおげさではないかと。