オブジェクト指向言語はもう要らない?

Scala界で有名なとある人が「オブジェクト指向は私にとって必要じゃない」という旨の発言をされていたので、えええ~っ、要らんの?要らんの!?と一瞬驚きましたが、冷静に考えたら私も最近はScalaではもちろんのこと、Javaなどのオブジェクト指向言語でもオブジェクト指向っぽく書いていないことに気づき、「要らんっちゃ要らんかなあ」と思い直しました。

それってオブジェクト指向なの?

私はJavaが嫌いです。ですが嫁と子供を食わした上にマツダCX-5のローンを払った上に一条工務店のニコニコ35年変動金利ローンを払った上にニコニコ投資信託積立内外資産為替ヘッジしないといけないので、嫌々仕事をしています。嫌々です。Scalaの時はイケイケですが、Scala使っていいよと言ってくれる人が少ないので大体、Java 8 + SpringBootで組んでいます。その次にC#が多いです。たまにSeasar2とかStrutsとかの案件がくると卒倒しそうになります。

※Scala知っている人が私の職場に私しか居ないため、Scalaで組むと私以外にはメンテできなくなるからだそうです。でも、どーせ何の言語で打っても俺がずっとメンテするんだろ、クソ。と思ってます。

Javaは嫌いなのであんまりよく知らないのですが、Javaはオブジェクト指向らしいですね。でも私はJavaでオブジェクト指向言語らしきプログラムを書いたのは大学時代にP2Pネットワークトポロジの研究をしていたときが最後で、それ以降は特にオブジェクト指向言語っぽいコードをJavaで書いていません。

SpringBootを使ったアプリケーション開発では、まずModelとViewとControllerを作ります。私はRESTが好きなので、Controllerを作るときは極力シンプルに書きます。Cookie読み取ってどうとかめんどくさくて分かりにくいことは避けます。Controllerクラスはなかにメソッドが並んでいるだけです。DBアクセスもJdbcTemplateなどを使って極力シンプルな実装にしたいのですが、いまだに「データベースのテーブルと全く同じ構造のEntityクラスを全部作ってそれを使いまわす」というこれもまた儀式的で面倒くさいことをさせられるので嫌々そうしています。

で、実際に動作させるときはアノーテションによるDIとかいう変態的で気持ち悪い仕組みでインスタンスが作られます。Controllerが呼ばれたらDBにアクセスして結果をEntityで包み、適宜なにかの処理をしてViewに渡します。Viewで何をやってるか知ったこっちゃないですが、究極的に言えば何かのオブジェクトを渡してHttpResponseを貰う(クライアントに返す)だけで、何か副作用のある処理をやっているわけではないと思います(やってるかもしれませんがあまり重要でない)。

これって、オブジェクト指向と言えますか?私はオブジェクト指向じゃないような気がします。

Wikipediaを調べてみましょうか。

オブジェクト指向(オブジェクトしこう)とは、オブジェクト同士の相互作用として、システムの振る舞いをとらえる考え方である。

と書いてあります。私が先に説明した要素の中に、「オブジェクト同士の相互作用」はあるでしょうか。単にgetter/setterで内部状態を変更するのは相互作用とは言いません。クラスやインスタンスというオブジェクト指向のエッセンスは使用していますが、それは単に値を包んでまとめたいとか、処理をわかり易くグループ化したいというだけの目的で利用されており、インスタンス間の相互作用は無いとおもうのですが、どうでしょうか。もちろん、SpringBoot本体内部の実装を紐解いていけばオブジェクト間の相互作用をフル活用している部分はあるでしょう。ListだろうがArrayだろうが拡張for文使えるのもiteratorインタフェースを実装しているというのもわかりますよ。しかし、私が使う範囲で「オブジェクト間の相互作用」を強く意識する場面はほとんど無い。その意味においては、私はオブジェクト指向していない。

関数言語を知らなくても関数言語的な書き方になってくる

Scalaでコードを打つ時は、もはや私は極力インスタンスに内部状態を持たせないように無意識に努力しています。内部状態があるとめんどくさいのです。私は馬鹿なのでいちいち管理できないんです。なので、なるべくcase classやobjectを使いますし、varで変数を定義することはほとんどありません。

関数言語的な書き方は私は全然分かりませんでしたが、最近はかなり理解できてきたように思えます。というか、Scalaで常識的な考えをもってしてコーディングしてれば勝手にそうなると思います。何かの集合に対してパイプラインのように処理を追加していき、目的のデータに加工するという作業をひたすら繰り返せばそれでよいのです。私はまた、デバッガをほとんど利用しないということに最近気づきました。昔ながらのprintデバッグで事足りるのです。オブジェクトの内部状態を詳しく見て回りたいという動機がまず無いのです。

そして、そういう書き方を覚えたあとでオブジェクト指向的な書き方をしたいか…というと、少なくともWebシステム開発ではやりたくないですね。

適材適所

じゃあ全然オブジェクト指向が要らないか、というとそういう訳でもないです。ぱっと思いつくのは、たとえばC#+WPFでMVVMモデルを実装したときなんかですね。あれは各オブジェクト間がメッセージ通信を行ってインタラクティブに相互作用を及ぼす操作を多用します。UIを構成する各パーツ間が相互に関係していて、一つの値が変更されたら他の部分も合わせて更新しなければならない、みたいなものを関数型言語で書くのはしんどそうです(私ができないだけで関数型言語をフルに使いこなせる人は出来るのかもしれませんが)。

あとは抽象的ですが、ゲームをプログラミングする場合も、オブジェクト指向的な考えをした方が良いシーンはたくさんありそうです。

まとめ

結局は適材適所ですね、で終わりで、今後もオブジェクト指向、関数型言語ともに残り続けるとは思いますが、特定の分野では関数型言語的な発想をすることはオブジェクト指向的な発想をするよりもずっと効率的だとまでは言ってもいいんじゃないかなと思います。