59
49

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

君のオブジェクト指向は間違っている。

Last updated at Posted at 2021-08-12

はじめに

はじめに敢えて断言しよう、君のオブジェクト指向は間違っている。
もし君がオブジェクト指向とは何かと聞かれて以下のように答えるなら、君は僕の授業を聞いていく必要がある。

オブジェクト指向とは、

  1. 手順ではなく、モノに着目する(車とか動物とか。てかオブジェクトの言葉そのままやん)
  2. 変数と処理をまとめたものだ(カプセル化)
  3. プログラムを再利用しやすくするためのものだ(継承)
  4. ポリモーフィズムを使える(いまいち理解できていない人が用語だけ出してきた感)

ちなみに上記のリストはGoogleで「オブジェクト指向」と検索して出てくるページに書いてあることを挙げたものだ。全くなっていない。挙句の果てには「オブジェクト指向は何かという問には答えがないから、なんとなくのイメージを掴んでいれば良い」などと言ってのける強者までもが出現する始末である。私はこのような解説記事が世に蔓延していることに驚きを隠せない。まともな記事1つ出てこないではないか。多分そこそこにソフトウェア開発をやったこともない者が書いているのであろう。てか絶対そうだ。

オブジェクト指向の本質はインターフェイス

オブジェクト指向というかソフトウェアの本質だが、重要なのは「それが何であるか」ということではなく「それが何をするのか」ということなのだ。これこそが機能と呼ばれるものである。ソフトウェアにおいて車が車であることなどどうでもよい。ただ目的地へ着けば良いのだ。これはソフトウェア特有の話であり現実世界であれば、車は車であることに価値がある場合もある。なぜなら現実世界のモノは見えるからだ。一方ソフトウェアにおいてそれが何であるかなど一般ピープルには見えない。それがどんな機能を持ちどんな効能をもたらすかにしか興味がないのである。
よって我々はモノに着目している場合ではない。機能に着目すべきなのだ。**インターフェイスとは機能をユーザー側の視点から記述したものだ。**これによって機能を構成するものの中でユーザーが知る必要のない情報(実装)を隠蔽するのである。各コンポーネントが自分が知る必要のあることだけを知ることで、現代の複雑かつ大規模なソフトウェア開発が可能になるのである。

変数と処理がどこにあるかなんてどうでも良い

これは言い過ぎかなと思うが、まあどうでも良いので仕方ない。カプセル化は大事だし全部の変数をpublicにしやがったら蹴っ飛ばしてやるところだが、実際これを最低限できてない人はあんまりいないんじゃないかな、皆ゲッターセッター大好きだしね。
私が言いたいのは変数と処理は実装であり、実装などユーザーにとってどうでもよいということなのだ。ちなみにユーザーとは現実のユーザーのみならず、ソフトウェア内部で該当クラスを利用しているモジュールも含めている。

継承は禁止だよ。

敢えて断言しよう(二回目)。継承なんてオブジェクト指向には必要ない。どころか有害である。オフィスの窓開け放ってかなぐり捨てることに躊躇してはならない。私は継承をごりごりやらかしているイタいコードを見ると体中に蕁麻疹ができてしまい、それが私の目前で行われた日には、どうやってチームメンバーに継承をやめて頂こうかと考えるあまり夜も眠れなくなってしまう。
継承が持つ重大な問題は私が考えるに2つある。1つ目はソフトウェアにおける根源的な話だが、継承によりベースクラスに処理を共通化したり、オーバーライドしたりするというのはつまり実装に依存するということなのだ。実装は変わりやすい。そして変わりやすいコードへの依存は最小限に抑えるべきなのだ。2つ目はスコープが広がってしまうことだ。継承先のクラスのコードを読むときに、変数・関数共にそれがこのクラスのものなのか、それとも継承元のものなのか確認せねばならない。書いた本人はわかっているから良いが、読む方はいちいちどのファイルに該当のコードがあるのかを探しに行かなくてはならないのだ。これは何でもできるスーパークラスを作ってスコープ広げるよりもたちが悪い。だってたくさんファイル開かなきゃいけないから。
とはいえ何でもかんでも禁止とは流石に言わない。例えばGUIは「何であるか(どう見えるか)」に重きがあるという点で継承を使うことが理にかなっている場合もある。
私が言いたいのは「処理を共通化したいから継承」は止しなさいということで、それをするなら別クラス(or 関数)に共通処理を切り出してそれをクラスに持たせて使いなさい(合成)、ということなのです。

さいごに

オブジェクト指向は非常に広範な事柄を指しているようで、実は突き詰めるとインターフェイスに行き着くのであります。皆様がこの記事をきっかけにオブジェクト指向についての考えを深めていただけると嬉しいです。
最後になりますが、散々人を間違え呼ばわりしてきましたが、次は私のターンだということは重々承知しておるつもりであります。はい、ブーメランですね。皆様どうかお手柔らかに…

59
49
17

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
59
49

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?