きしだのはてな このページをアンテナに追加 RSSフィード

2014-07-18(金) オブジェクト指向は禁止するべき

オブジェクト指向は禁止するべき 22:46 オブジェクト指向は禁止するべきを含むブックマーク Add Starpapiro (green)species5618jp (green)osiire35arieee0

プログラムがまだ不慣れな人が「プログラムちょっとわかるようになったけど、まだぜんぜんオブジェクト指向とかできてません」のように言ったり、ちょっと慣れた人が「このソース、ぜんぜんだめ。オブジェクト指向ができてない」にようなことを言ったり、まるで、オブジェクト指向ができてるかどうかがよいプログラムかどうかを表すことになってるようだ。

Javaアルゴリズムの本に、「Javaなのにオブジェクト指向ができていない」のような書評がついているのを見たときには、お前は何を求めてるんだと思ったりもした。


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


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

こういうコードはかなり困る。


こんなのもあった。

オブジェクト指向できていますか?

「理想的なオブジェクト指向の世界とは、小さな大量のオブジェクトがお互いメッセージを送りながら協調し複雑なシステムを構築する。各クラスは、1つの機能に集中し、最小限のインターフェースで構成されています。」

だそうだ。

とてもすばらしい世界だけど、プログラム組むときには忘れたほうがいい。

オブジェクト指向迷路ができるだけだ。


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


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


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


クラスは単にユーザー定義型であり、継承は部分型と差分プログラミングを実現する仕組みだととらえるのがいい。

オブジェクトがメッセージを送りあうとかメルヘンの世界には入らず、機能だけ考えるのがいい。


コードの基準としても機能的なものをまず考えたほうがいい。

一番大事な基準は、変数の数だと思う。プログラムは、引数やフィールドも含めて、変数の数が少ないほうがえらい。

ただしここで、再代入のない、状態変更もないローカル変数はカウントしない。

再代入や状態変更がない変数を除くと、残る変数は状態を管理するものになる。プログラムにおいて、管理する状態が少なければ少ないほどえらい。

残りの指標はあとでついてくる。必然的にコードの重複も減り長さも短くなる。コードの複雑さも減る。


ここで、変数の数やコードの長さに大差ない、数とおりの書き方があって迷ったときに初めて、責務や凝集度のような指標でコードの指針をえらぶ。

つまり、「責務としてはこっちだけど、コードが単純になるからこのコード」は許されるけど「コードは複雑になるけど、責務としてはこのクラスに書くべきだからこのコード」というのはほとんどの場合よくないコードになる。


そのように、複雑度を下げることを指標としてプログラムを書いていると、「オブジェクト指向する」という感覚にはならない。単にプログラム言語と向き合うだけになる。

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


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

かくして、オブジェクト指向は禁止するべき、という結論になる。


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


※2017/4/13 追記

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

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

masterqmasterq 2014/07/19 01:12 UMLやMDAについても一言おねがいします。

masterqmasterq 2014/07/19 01:37 あ、それから現在において、設計の安全性に貢献しない高階な型をいま良かれと思って使っている風習もそのうち同じ結論をたどるかもしれません。。。

疑問点疑問点 2014/07/19 03:09 これって一切の再利用をしない前提の使い捨てプログラムの話ですよね?

ヒゲヒゲ 2014/07/19 05:51 使い捨てプログラミングという前提はどこにも無い。それどころか「差分プログラミング」とまではっきり言っている。

ティーケーエムアールティーケーエムアール 2014/07/19 09:45 > むだにHogeインタフェースとHogeImplクラスがあったり、
What(問題領域)の世界をインタフェースや抽象クラスで表現し、Howのところを具象クラスでやるっていう感じなんでしょうかね。
ただ、以下のいずれにも「該当しない」のであれば無駄だと思います
 (1)問題領域を解く方法がそんなに変化しない、
 (2)問題領域を解く方法を変更してもほかに大きな影響がない、
 (3)さまざまな環境で運用されることが想定され、問題領域を解く方法が環境毎に変化する、かつ変化が頻発(いろんな環境で使われる)する

まあ、設計的にいえば抽象化を一段噛ますのであれば、ちゃんと変化点と影響範囲見極めろ、ってことですかね。。。


>どこで値が設定されてるかわからないオブジェクトがひきまわされてたり
これは困りますね。ただ、パッケージ間インタフェースやレイヤリングの設計をミスっているとどんな言語でも起こる気がする。あとはデータフローがちゃんと設計されてないだけかも。。。

というか、書籍化されたオブジェクト指向の解説って、エンプラ系の新規システム開発に特化してる気がする。。。組み込み系/Web系、あるいは派生開発でそのまま使うのは難しいのもしれない。

オージス総研の人に話を聞いてみたいなあ。。。

IGIG 2014/07/19 13:02 ここでいう「オブジェクト指向」は、「ファンタジックな指標を与え」るものとしての「オブジェクト指向」ということですね。Joel on Software では「宇宙飛行士」と称していましたが。初期の J2EE が失敗例として挙げられることが多いですね。Sun(当時) の開発者自身が失敗と認めていましたね。コードを書かずに、「オブジェクト指向設計のドキュメント」で先に設計したのが大失敗の原因だったと。

つまり、ここでいう「オブジェクト指向」は、現実のプログラム コードの機能・性能に何ら貢献しない「オブジェクト指向」のことでしょう。「そのようなオブジェクト指向は、窓から投げ捨てるべき」というのは、そのとおりと思います。

gomocorogomocoro 2014/07/19 14:51 タイトルは過激だけど、一言でいうと「下手くそなオブジェクト指向はやめろ」ということであって、それはそのとおりだと思います。ただ、指摘している内容とタイトルがあってないので、初心者の方の誤解を生むし、このタイトルは良くないと思いました。沢山の人に呼んでもらうために、過激なタイトルを付ける手法かと思われます。

プログラミングは眠るのも忘れてプログラミングは眠るのも忘れて 2014/07/19 22:46 あー、なんとなく同感するところあるわー
オブジェクトって、変数にインターフェース(メソッド)つけたもの、
って理解しておくのがよさそう。

鋼のアーキテクト鋼のアーキテクト 2014/07/21 16:45 言わんとしている事はわかる。
が、OOP禁止はやりすぎ。禁止してしまうとフレームワークがうまく設計出来なくなる。
アーキテクチャチーム(もしくは方式チーム)のようにフレームワークや共通部品を作るチームにはOOPは必須だと思う。
業務ロジックを実装するチームはその部品を使うだけだろうから、無くても困らないと思うが。

名無し名無し 2014/07/24 13:15 どこぞやの関数型の性質を持ったプロトタイプベースOOPが最強ということでよろしいか?

babydaemonsbabydaemons 2014/07/24 22:42 鋼のアーキテクトさん:
ここで言うOOP禁止というのは、携わる業務に特化したフレームワーク・共通部品(RubyではDSL)を
作れないITドカタやコピペプログラマは無理してOOPで作るな、人様が作ったフレームワーク・共通部品の恩恵に
預かっておけと言うように理解しました。

勉強中勉強中 2014/07/25 15:10 IGさんへ
 >初期の J2EE が失敗例として挙げられることが多いですね。
 >Sun(当時) の開発者自身が失敗と認めていましたね。
 >コードを書かずに、「オブジェクト指向設計のドキュメント」で
 >先に設計したのが大失敗の原因だったと。
この辺の事を詳しく知りたいので、もし何かlink先や記事を御存知でしたらお教え下さい。

もりもり 2014/08/26 00:03 >「複雑度を下げることを指標としてプログラムを書いていると、
>「オブジェクト指向する」という感覚にはならない。単にプログラム言語と向き合うだけになる。」
複雑度を下げるために責務とか、凝集度等を考えることになると思いますが。
機能的に考えるだけで複雑さが下がるという考えは
プログラムを作成するときに発生する問題を単純化しすぎだと思います。

nowokaynowokay 2014/08/29 20:58 結局は、メソッドの呼び出し数とか、状態の持ち回り数とか、そういう話になると思います。
責務とか凝集度とかは、その方向性のヒントになるだけで、最終的にはコードがどうなるかというイメージを持ってコードを書くのがいいと思います。最後には必ずコードになるわけで、そこを最適化するのが目標なので。

chungzeechungzee 2014/09/02 15:35 メイヤーを読了したのであればちょっとご意見を聞かせてください。
メイヤーが「オブジェクト指向入門」で言及しているOCPと、ボブマーチンが「アジャイルソフトウェア開発の原則」で述べているOCPは同じだと思いますか?違うとすればどのような点ですか?

あ 2015/01/18 01:15 自己満足な記事ですね

ぺーぺーぺーぺー 2015/12/18 08:59 OOPで大事なのはブラックボックスで協調するという点のみ
重要なのは再利用性だけだから、ライブラリがついているなら問題無い。
作成されたオブジェクトにどの程度の成約事項がついているか、実行速度がどの程度かそれだけが指標。

また他人が作ったオブジェクトについて、ソースの中身に言及するのがナンセンス、そういうのは教育の現場でのみやること。

foobarfoobar 2016/12/11 23:23 >むだにnewするだけのcreateメソッドがあったり
これよくある、笑ってしまったw
無駄に色んなデザインパターン詰め込んであるけど、
自己満足のためだけでまったく利用されてないやつねw
インターフェイスとImplを分けてるのも、
他の利用者がろくにifクラスを使わなくてほとんど意味なかったりとかw

信者信者 2016/12/18 17:53 面白い意見だと思いました。デザインパターンとアジャイル開発についてはどう思われるのでしょうか。

nowokaynowokay 2016/12/27 05:53 デザインパターン、GoFのデザインパターンについては、90年代のC++の言語制約上できなかったことをいかに実装するかという話で、ほとんどが関数式がある言語では不要になっているし、フレームワークという考え方のほうが広く使われるようになったしで、4月ごろに雑誌にでる気の利いた記事を読んで今でも使ういくつかのパターンを知っておけばいいかな、という感じです。
アジャイルは、よくわかんない。というのが答え。あと、変なこというと刺される雰囲気がある。

オブジェクト指向の謎オブジェクト指向の謎 2018/06/23 21:26 JavaやC#の謎は関数を定義するために名前空間とクラスを必要とするところだ
名前空間はまだわかる、なんで関数(static method)の宣言にクラスが必要なんだ?
正直Javaで関数書く気なんてしないし、言い換えればJavaでプログラム書きたくない
関数こそプログラミング抽象化の基礎であり、オブジェクト指向論者が好んで用いるSOLIDや再利用性を本当に満たすのはクラスじゃなくて関数だと思う
(純粋)純粋関数的に実装していれば、再利用性も組み合わせ利用もソース記述も比較的シンプルに行える。それではほしい分のパフォーマンス出ないから状態使いますよ、それをうまいこと隠蔽しますよってならクラス使う意味が凄くわかる。
オブジェクト指向が提唱する概念ってほとんどがオブジェクト指向がサポートしない概念、言い換えればないものねだり、UNIXのシェル(パイプ)とか関数型言語のmap reduceのほうがどう考えても再利用性が高いしインターフェースが簡潔に保たれている
当時のマイクロソフトやサンが営業攻勢にかけていたから、オブジェクト指向は広く普及したが、数学や哲学的なバックグラウンドが無いに等しいから中途半端だ
再利用性を求めるなら関数型プログラミング、パフォーマンスを求めるなら弱い型付けのビット列の変換としてCで書く、その折衷案であるオブジェクト指向から入るとどっちつかずにしかなれない

トラックバック - http://d.hatena.ne.jp/nowokay/20140718