オブジェクト指向は禁止するべき

プログラムがまだ不慣れな人が「プログラムちょっとわかるようになったけど、まだぜんぜんオブジェクト指向とかできてません」のように言ったり、ちょっと慣れた人が「このソース、ぜんぜんだめ。オブジェクト指向ができてない」にようなことを言ったり、まるで、オブジェクト指向ができてるかどうかがよいプログラムかどうかを表すことになってるようだ。
Javaアルゴリズムの本に、「Javaなのにオブジェクト指向ができていない」のような書評がついているのを見たときには、お前は何を求めてるんだと思ったりもした。

そのようなオブジェクト指向は、窓から投げ捨てるべきだ。オブジェクト指向はプログラムのよしあしの基準にならない。

むだにHogeインタフェースとHogeImplクラスがあったり、むだにnewするだけのcreateメソッドがあったり、どこで値が設定されてるかわからないオブジェクトがひきまわされてたり、ソースコードを追いにくくするためにやってるとしか思えない、オブジェクト指向なコードをよく目にする。
こういうコードはかなり困る。

こんなのもあった。
オブジェクト指向できていますか?
「理想的なオブジェクト指向の世界とは、小さな大量のオブジェクトがお互いメッセージを送りながら協調し複雑なシステムを構築する。各クラスは、1つの機能に集中し、最小限のインターフェースで構成されています。」
だそうだ。
とてもすばらしい世界だけど、プログラム組むときには忘れたほうがいい。
オブジェクト指向迷路ができるだけだ。

こんなことだから「オブジェクト指向でコーディングするとinterfaceやAbstractなど記載量とファイル数が増え、工数が増大すると思います。」などと素朴に言われたり、「プログラマがすることといえば、自分の手であり得ないほど複雑に加工してしまった、神聖なるAPIに対してだけは責任を持つと声高に主張することです。その割には、ほとんどうまく機能しませんが」などと言われるのです。

もう、オブジェクト指向は禁止したほうがいい。人類には早すぎたのだ。

ここで、オブジェクト指向が禁止なら継承もできないのか、のように、裏返せば継承つかったらオブジェクト指向のような認識であるなら、メイヤーの「オブジェクト指向入門」2冊を隅から隅まで読んで出直すべきだ*1

クラスは単にユーザー定義型であり、継承は部分型と差分プログラミングを実現する仕組みだととらえるのがいい。
オブジェクトがメッセージを送りあうとかメルヘンの世界には入らず、機能だけ考えるのがいい。

コードの基準としても機能的なものをまず考えたほうがいい。
一番大事な基準は、変数の数だと思う。プログラムは、引数やフィールドも含めて、変数の数が少ないほうがえらい。
ただしここで、再代入のない、状態変更もないローカル変数はカウントしない。
再代入や状態変更がない変数を除くと、残る変数は状態を管理するものになる。プログラムにおいて、管理する状態が少なければ少ないほどえらい。
残りの指標はあとでついてくる。必然的にコードの重複も減り長さも短くなる。コードの複雑さも減る。

ここで、変数の数やコードの長さに大差ない、数とおりの書き方があって迷ったときに初めて、責務や凝集度のような指標でコードの指針をえらぶ。
つまり、「責務としてはこっちだけど、コードが単純になるからこのコード」は許されるけど「コードは複雑になるけど、責務としてはこのクラスに書くべきだからこのコード」というのはほとんどの場合よくないコードになる。

そのように、複雑度を下げることを指標としてプログラムを書いていると、「オブジェクト指向する」という感覚にはならない。単にプログラム言語と向き合うだけになる。
ただ、ここに書いているようなプログラムへのストイックな向き合い方は、プログラムに不慣れな人には難しい。責務や粒度のようなファンタジックな指標のほうが、なじみやすいと思う。けれど、そのようにプログラムに不慣れな人にファンタジックな指標を与えても、ファンタジーあふれた夢の城のような無駄の多いプログラムができるだけだ。

プログラムに慣れた人はオブジェクト指向する必要がなく、プログラムに不慣れな人がオブジェクト指向すると全力で迷路を構築してしまう。
かくして、オブジェクト指向は禁止するべき、という結論になる。

ところで、オブジェクト指向入門、この本は、ぜんぜんオブジェクト指向してない。1800ページもあるし、ある程度は型理論とかを知らないと読みにくいという点では入門でもない。オブジェクト機能をもつプログラミング言語についていろいろな角度から説明した本で、興味あるとこだけ読んでもおもしろい。厚みもかなりあるので、夏休みの昼寝の枕におすすめ。

※2017/4/13 追記
こちらの書籍の「オブジェクト指向まぼろしか?」という記事で、オブジェクト指向の歴史的な流れから、どのようにオブジェクト指向は使われなくなったかということを書いています。

*1:深い意味はないが時間稼ぎになる