acomagu's diary

思ったことを書きます。技術的なことは書きません。

オブジェクト指向は難しくない(「staticおじさんの逆襲」への反論)

qiita.com

これを読んでいろいろと言いたいことが出てきたので書いておく。

以下に記事の最後のこの記事で言いたかったことから2つを引用します。

オブジェクト指向は難しい。

(どのあたりのことを「難しい」と言っているのだろう)まず「継承は難しい」旨が書いてあるが、それはオブジェクト指向使いの中でも常識で別に継承無しでもオブジェクト指向はできる。「継承よりもコンポジション」というのは間違っても「オブジェクト指向はダメだ」というメッセージではなく、オブジェクト指向の中での方法の話である。

デザインパターンが難しい」という話も同じで、別にデザインパターンを意識しなくてもオブジェクト指向は十分にできる*1

ただ、だからといってオブジェクト指向をやるのが難しくないというわけでもない。「問題を(オブジェクトに)抽象化するのが難しい」と言っているのであればそれはそうで、適切な抽象化を簡単にする方法はまだ誰も見つけていないように思えるし、適切な抽象化が無いことにはオブジェクト指向のメリットは得られない。ただし、「適切な抽象」を考えることは本質的には課題を理解し分割して名前をつけるようなものなので、関数型プログラミングならそれなしにできるかというと疑問だ。

例えば「円からドルへの変換」するプログラムを関数型パラダイムを使用して書くことを考えてみたいと思う。これは単純で、円の値にドルへの為替レートを掛ければ良いと思う。じゃあそこで「ドルから円」「円からユーロ」の変換する必要も出てきたらどうだろうか。「円」や「ユーロ」は「通貨」へ、「円からドルへの変換」は「通貨から通貨への変換」へと抽象化したくなるのではないだろうか。すべての抽象化はその延長上にある。オブジェクト指向でもほぼ同じで、それらの違いはデータ(「通貨」)と操作(「変換」)を近くに置いてより豊かな抽象的表現を追求するか、あるいはそうではなく純粋関数から得られるメリットを重視するか程度だと思う。

よってオブジェクト指向が特に難しいわけではなく「オブジェクト指向では抽象化がより重視されている(そして抽象化は難しい)」程度の認識が正しいのかなと思う。抽象化なしにはプログラムの可読性も柔軟性も(正しい変数名さえも)得られないので、その点で関数型プログラミングのほうが優れているということは無いと思う。

複雑さはそれ自体害悪である。単純なのはよいことだ。

「単純」がどのベクトルを指して言っているのかいまいちわからないけれど、例えばそれが「コード量」の話であるなら最も単純なのはオブジェクト指向でも関数型でもなく、命令型プログラミングになると思う。

オブジェクト指向でも「抽象化しすぎ」という状態はある。例に上がっている「FizzBuzzEnterprizeEdition」は明らかにその状態だと思う。可読性や柔軟性が十分であるのにそれ以上のカプセル化ポリモーフィズムを多用することが無意味な複雑化につながることは想像に難くない。

元記事に書いてあるとおり、僕達は「複雑な課題を簡単に解決する」ために抽象化に頭をひねらせる。課題が十分に複雑でないなら、抽象化なんて要らない。

まとめ

  • オブジェクト指向は難しくない。難しいのは抽象化である。
  • 継承もデザパタオブジェクト指向プログラミングをする上で必須なものではない
  • 抽象化こそがプログラムの可読性と柔軟性を作り出す(これは元記事にも書いてある)
  • どちらにせよ抽象化し過ぎは悪。

思ったこと

自分も数年前までは「これからは関数型の時代だ!」と思ってオブジェクト指向を禄にやっていなかったのだが、いろいろあってちゃんと勉強したら「長く支持されているものにはちゃんとした理由があるのだなあ」と実感した勢なので、「オブジェクト指向よく知らないけれどオワコンなんじゃないの?」と思っている人たちは一度どっぷり浸かってみてほしいと思う。

おわり

*1:そもそもデザインパターンは言ってしまえば「パターン」でしかないのでオブジェクト指向の本質でもなんでもない。(個人的には)使えるときに使ったらいいという感覚