• 締切済み

本当にオブジェクト指向プログラミングっていいのでしょうか?

shu-tecの回答

  • shu-tec
  • ベストアンサー率0% (0/0)
回答No.16

オブジェクト指向を学ぶ上で引っかかりそうな謎などについて、ちらほら書いてみました。 質問者さんもいい加減食傷気味だろうなとは思いつつ、結局長文になってしまいました。 申し訳ありませんが、参考になれば幸いです。 ■「オブジェクト指向」の説明が収束しないわけ 一口にオブジェクト指向といっても、いくつか流派があります。 この辺、以下のサイトが参考になります。 オブジェクト指向の概念の発明者は誰ですか? http://d.hatena.ne.jp/sumim/20040525/p1 このサイトを参考にしつつ至った私の結論では、オブジェクト指向の流派は大雑把にC++派、SmallTalk派、JavaScript派の3つに分かれます。 C++派代表はもちろんC++、SmallTalk派では、Macプログラミング界でメジャーなObjective Cがあります。 Javaは、C++をベースにしつつ、ちょっとSmallTalk側に傾いた印象で、C#も基本はJavaを踏襲しています。 JavaScript派はかなり特異なので、あまり混乱することはないと思いますが、C#2.0は若干JavaScriptっぽくなったというウワサです。 参考: http://www.atmarkit.co.jp/fdotnet/csharp20/csharp20_01/csharp20_01_01.html それぞれの流派では、中心に据える概念が違います。 C++派ではオブジェクトが中心ですが、SmallTalk派ではオブジェクト間の通信である「メッセージ」が中心です。 また、使う言葉も結構違います。(フィールドとかメソッドとかいうのは、主にSmallTalk流。仮想関数とかメンバとかはC++流) このため、どの流派に軸足を置くかで、オブジェクト指向の説明(というか解釈)がまず大きく変わります。 さらに、多くの人は、それぞれの流派の概念を混ぜ合わせたり、いいとこ取りをしたり、経験的に有効な手法を組み合わせて身につけていたりするので、その配合割合によっても解釈が変わり得ます。 さらにさらに、ちゃんと理解できてなさそうな著者が書いたような書籍も世に溢れています。 そんな本を読んで、それすらちゃんと理解できないままに、分かったつもりになっている人も大勢います。 カオスもここに極まれり、です。 ■本の読み方 そんなわけなので、書籍で学ぶ上での勧めの指針をいくつか。 1.できればC++で説明している本を選ぶ。 最初の頃は、複数の用語が出てくると混乱の元だと思います。 C++で説明している本に絞れば、用語がかなり統一されますので、混乱が減るのではと思います。 また、Javaのオブジェクト指向は比較的C++に近いので、それでもいいかもしれません。 Objective CとかSmallTalkの本は、「自分の中のオブジェクト指向像」が出来ていない間はお勧めしません。 この段階では、とりあえず「メッセージ」を強調した本は避けておくのが吉だと思います。 2.オブジェクト指向に限定せずに読む。 やや回り道ながら個人的にお勧めの方法は、C++設計技法を紹介した本の乱読です。 その中には、オブジェクト指向を生かしたテクニックもあるし、C++特有のものもあるし、C時代から変わらないテクニックも、時代の先端を行き過ぎた変態テクニックもあります。 そんなのをたくさん読んでいくうちに、「あ、こーいうのがC++によるプログラムの組み方なのかなー」と分かってくると思います。 そんな中で、C++によるオブジェクト指向というのも見えてくると思います。 それがおぼろげに見えた段階でオブジェクト指向の良書を読むと、目からうろこがぽろぽろと、面白いほどよく落ちるでしょう。 3.たくさん読む。 「オブジェクト指向」の解釈は無数にあるので、どれが正しいかは自分の目で見極める必要があります。 そのためには、いろんな解釈をみて、それぞれの利点、欠点、矛盾点などを、自分の経験に照らして考えなければなりません。 4.最後に、いろんなオブジェクト指向の本を読む。 Javaの本とか、Objective Cの本とか、SmallTalkの本とか、C++ではない本を読むと、オブジェクト指向の世界が広がります。 中には、C++の主張と全く逆の主張もあったりして、「結局どっちが正しいの?」と言いたくなる事もあります。 結局どっちが正しいのかは自分で考えて判断するしかなく、そのためにはある程度「自分で考える基盤」が必要なので、これはある程度オブジェクト指向が分かってきてからのほうがいいでしょう。 ■お勧めの書籍 ○Effective C++ (Scott Meyers)  C++設計技法の決定版。これを読まずしてC++は語れない! ○C++ Coding Standards (Herb Sutter, Andrei Alexandrescu)  Effective C++並に使える本です。 ○C++プログラミングの処方箋 (Stepehn C. Dewhurst)  内容はそこそこ高度ですが、読みにくくはありません。  オブジェクト指向に関するトピックがわりと多いです。 ○デザインパターンとともに学ぶオブジェクト指向のこころ  (アラン・シャロウェイ, ジェームズ・R・トロット)  私の目からうろこを落とした本です。  ある程度「オブジェクト指向」のイメージができてから読むといいかもしれません。 ・Effective STL (Scott Meyers)  Effective C++と同じ作者による、STL(C++標準ライブラリの一部)を使用する上でのガイドライン。  ちなみにSTLは非常に有用なクラスライブラリですが、オブジェクト指向ではありません。 ・More Effective C++ (Scott Meyers)  Effective 3部作でもっとも内容が高度な上、奇妙な翻訳も多い。  内容はいいのですが、読みにくさはピカイチです。 ・Exceptional C++ (Harb Sutter)  C++やオブジェクト指向の設計について、クイズ形式で問題点と解決法を紹介。  Effective C++よりやや上級? ・Modern C++ Design (Andrei Alexandrescu)  「いい言葉に力を与えるには悪い言葉も知らなきゃいけないって、でも決して使うなって。」  そんなバルスな感じの変態テクニックが満載です。 ・オブジェクト指向における再利用のためのデザインパターン  (Erich Gamma, Ralph Johnson, Richard Helm, John Vlissides)  通称GoF本。その偉大さはGoogle先生に聞いてみてください。 ・リファクタリング (Martin Fowler)  通称リファクタ本。オブジェクト指向に関する名著の一つです。 ・パターン指向リファクタリング入門 (ジョシュア・ケリーエブスキー)  GoF本、リファクタ本と合わせて3部作なイメージです。セットでどうぞ。 ○をつけたのが特にお勧め、・をつけたのは、その後で読んでみるといいかもです。 アジャイル関連の本は、SmallTalkの息がかかっていることが多いように思うので、最初のうちはあまりお勧めしません。 もちろん、わかって読めば非常に有用ですが、オブジェクト指向の初学者には混乱を招く要素が多い気がします。 なお、『C++プログラミングの処方箋』の「全宇宙的なクラス階層」という項目では、他のオブジェクト指向言語では常識である「Objectクラスを頂点とするクラス階層」を完全否定しています。 こういう矛盾に気付いて行き詰まったら、とりあえず深く考えずに次へ進むことをお勧めします。 その後数冊読んだ後で再び読み返してみると、すんなり分かるってことも多いものです。 ちなみに、全宇宙的なクラス階層に関する見解の相違については、C++がオブジェクト指向【専用】言語ではないと分かれば納得できます。 ■お勧めできない書籍 『憂鬱なプログラマのためのオブジェクト指向開発講座』 通称憂鬱本。ツッコミどころ満載です。逆にお勧めです! ただ、悪書も悪書で読んでみてもいいかもしれません。 良書or悪書と人が言ったから、というのではなく、自分で判断できるようになるために、清濁併せ呑み皿まで食らって、自分の頭で考える、というのが、迂遠ながらもやっぱり通るべき道かな、と思います。 ■手続き型は大変だけど、オブジェクト指向はすばらしい例 オブジェクト指向の本では、たまにこういう比較をしているものがありますが、その手の本には正直眉をひそめたくなるものが多いです。 よくあるのは、非オブジェクト指向の設計を極端に貶めている例。そして、オブジェクト指向を過度に賛美している例。 とりあえず憂鬱本の作者はC言語に謝れと言いたい。 多分、これらを平等に比較するのはかなり難しいんだと思います。 『オブジェクト指向のこころ』では、(あくまで主観ですが)あまり不自然でない形で機能分割、従来のオブジェクト指向、正しいオブジェクト指向の3つの設計を比較しています。 ■そもそもオブジェクト指向の利点とは? 私の理解では、オブジェクト指向というのは「変更に強いプログラムの作り方」です。 だから、オブジェクト指向設計が成功したかどうかは、実際に仕様変更の波に晒してみないと分かりません。 オブジェクト指向では、「変更がなさそうな部分」と「変更がありそうな部分」を分析し、変更がありそうな部分に対して、ありうる変更を施しやすいように設計します。その読みが外れていれば、いかにオブジェクト指向で作ろうが、ダメ設計になります。 しかし、上手く設計すれば、機能分割による設計よりも変更箇所を局所化できます。 つまり、出来上がったプログラムに対して仕様変更要求が発生したときに、オブジェクト指向は真価を発揮します。 言い換えれば、仕様変更がないものや、変更するより作り直したほうが早いような小さなプログラムでは、特に利点はありません。 なお、オブジェクト指向に限らず「複雑な設計を整理して、単純化するための仕組み」というのは、それ自体も若干複雑なものです。 それによって増える複雑さよりも、単純化による効能の方が大きい場合に、それは価値を発揮します。 逆に、元々が非常に単純な設計であれば、「複雑さを緩和する仕組み」そのものの複雑さが単に加わることになります。 小さなプログラムで逆に面倒に感じるのは、そういう問題もあるのかもしれません。 ■多重継承について 実装を含む多重継承の好例は、C++標準ライブラリのstd::iostreamクラスです。 このクラスの設計に対する不満はあまり聞かないので、よい例に数えられているのだと思います。 (標準ライブラリの中にも「悪い設計」と評判のものがいくつかあるので要注意です!) ただし、このような多重継承を【正しく】使うには、仮想継承や基底クラスメンバのusing、仮想基底クラスの初期化に関する制約、オブジェクトのメモリレイアウト、static_castやdynamic_castが裏でやっていることこと、等々、相当マニアックな事柄を完全に把握しなければなりません。 さらに、多重継承を【効果的に】使うには、多重継承による効果とそれがもたらす決して小さくない制約を比較して、それが一番いいと判断できる、非常に高い設計能力が必要です。 普通人には無理、ということでファイナルアンサーにしていいと思います。 ちなみに、実装を含まないクラスであれば、多重継承してもあまり問題を引き起こさないということがわかっています。 実装を含まないクラスとは、メンバ変数を持たず、メンバ関数の実装も持たない、つまり純粋仮想関数のみから成るクラスです。 JavaやC#ではそういうクラスを明確に区別するために、実装を含まないクラスを「interface」と名付け、「class」は実装を含むクラスだけを指すようにしました。 そして、classは一つしか継承したらダメけど、interfaceはいくつ継承(というか実装)してもいい、というルールにしたのです。 C++の自由かつ危険な部分にフタをして、安全設計にしているわけですね。 ■インターフェイスとクラスの設計 >・インターフェイスにくっつくクラスはどれか? >・そのクラス達に共通するものはないか? >・共通したものを基本クラスとする >という思考で設計していけば、OOP設計に近づくことが出来るのでしょうか。 その中で、「インターフェイス」を設計するところに一番重点を置くと、OOP設計に近づきそうな気がします。 それ以外の、インターフェイスにくっつくクラスを作ったり、共通部分を基本クラスにまとめたりするのは、あくまでインターフェイスの後ろでコソコソやればいい「実装」に過ぎません。 主役はインターフェイスです。 ・【それ】は何ができるべきか? どんな情報を持つべきか? ・【それ】の機能や情報に、他のオブジェクトからどうやってアクセスするか? ・【それ】が持つ機能や特徴へのアクセス手段を、インターフェイスとしてまとめる。 ・機能を実現し、特徴を保持するための実装を考える。 という思考の方が、よりOOPに近いと思います。 >簡単に対象、機能を切り替えられる ようにするには、インターフェイスを「実装を持たないクラス」として作成し、実装はすべてその派生クラスに置くようにします。 クラスを使うときは、インターフェイスとなっている「実装を持たないクラス」だけにアクセスし、派生クラスは存在しないものとして扱います。 異なる実装を持つ新しい派生クラスを作って、もとの実装と入れ替えれば、クラスを使う側は一切変更しないままに「簡単に機能を切り替えられる」わけです。 ところで、「共通したものを基本クラスとする」というのは、#1さんが言う「実装の継承」なので、「悪い設計のサイン」に当たりそうです。 基本クラスにまとめるのではなく、別クラスにまとめてそれをメンバ変数として保持するというのが、一般に継承を使うよりもいい方法だといわれています。 class Base {}; class Class1 : public Base {}; class Class2 : public Base {}; ではなく、 class Common {}; class Class1 { private: Common m_common; }; class Class2 { private: Common m_common; }; とするわけです。 こうしたほうがいい理由は、『Effective C++』に詳しく書いてあります。

参考URL:
http://d.hatena.ne.jp/sumim/20040525/p1

関連するQ&A

  • オブジェクト指向プログラミング

    一般に、オブジェクト指向プログラミングといわれているプログラミングに関してですが、 「関数・手続きを使用するプログラミング」と 「クラスを作成してプログラミング」というのは おおきな違いがあるのでしょうか? (クラスを作成しなくても関数・手続きで、プログラミングすれば 一緒じゃないかなぁと思っていますので・・・。) どなたか、これに関して、お返事をして頂けたら今後いろいろな面でかなり助かります。

  • オブジェクト指向プログラミングはどのように使用(適用)する?

    あるシステム、またはフリーソフトでもいいのですが、 オブジェクト指向によるプログラミングを行おうとするとき、 そのシステム(ソフトウェア)全体に使用(適用)するのでしょうか? 書籍で学んでいると、オブジェクト指向プログラミングをする場合には オブジェクトとオブジェクトを組み合わせてゆくように書かれています。 もちろん、仕組みはそうではあると思いますが、 無理にシステム全体でオブジェクト指向プログラミングをする必要はなく、 たとえばシステム内である処理を行おうとしたとき、 オブジェクト指向プログラミングの方がいい場合に適用すればいいのではないでしょか?

  • オブジェクト指向の特徴

    プログラミングにおいて Java言語などのオブジェクト指向とは 「クラス(設計図)からインスタンス(実体)を量産できる。」がオブジェクト指向ではないプログラミング言語との決定的な違いなのでしょうか? またオブジェクト指向とオブジェクト指向ではない言語の決定的な違いや 実際に実務において経験した感覚的な違いなどがあれば教えてください。 インターネットに乗っていない些細なことでも構いません。

    • ベストアンサー
    • Java
  • オブジェクト指向に関して。

    Javaの解説本を読んでオブジェクト指向プログラミングという物があることをしりました。その本には「オブジェクトはデータとそのデータを扱うための機能を持っている。この機能はメソッドと呼ぶ。クラスは設計図のような物で変数とメソッドから構成されている。設計図を実際に形にした物がインスタンスである。」と書いてありました。私はオブジェクト=クラスのような感じがしたのですが、実際のところオブジェクト=クラスでいいのでしょうか?  また、友人に話したところ、オブジェクト指向はサブルーチンに似ているといっていました。私はプログラミングの知識が全くないのでサブルーチンという物が何なのかわからないのですが、サブルーチンとオブジェクト指向の考え方は違うような気がするのです。友人に説明して納得させるにはどうしたら良いのでしょうか? ぜひ、力を課してください。

  • オブジェクト指向、理解しやすい?

     最近、Javaの解説書や解説サイトを見ていて、しばしば、「Javaは完全なオブジェクト指向だから理解しやすい」といった記述を見かけます。(「プログラムが見やすくなる」とかではなく)  Javaに限った話ではないのですが、個人的に、オブジェクト指向の概念は、プログラミング初心者の最大の関門ではないかと勝手に思っています。僕はPHPから入ったのですが、ある程度基本事項をマスターした後も、オブジェクト指向だけは長い間苦手としてきました。(最近やっと慣れてきたところです。)  そこで伺いたいのですが、最初にやったプログラミング言語がオブジェクト指向だったという方、オブジェクト指向の概念は、 1.わかりやすかった 2.そこでつまずいた 3.特に意識せずに通り過ぎた 4.その他 いずれでしょうか? ※最初にJavaについて書きましたが、これはただの例なので、オブジェクト指向言語全般についての質問であるととらえてください。

  • オブジェクト指向プログラミングの多態性のメリット、目的は?

    オブジェクト指向プログラミングを学んでいます。 基本概念の多態性がどうも理解できません。 メリット、目的はなんなのでしょうか? 上位クラスを継承し、 その継承されたクラスのメソッドを上書きするということと何が違うのでしょうか? 学習の参考にしている書籍の中には ”多態性を使ったオブジェクト指向プログラミングの典型例”として、 異種リスト(=上位型に下位型を代入し、一族のオブジェクトを一括管理する)を紹介しています。 多態性はこのような使用のみを目的としているのでしょうか?

  • オブジェクト指向

    Perlの学習をはじめて2日目の初心者です。 Perlにおいて、オブジェクト指向をもちいて開発をしなくてはならないのです。 何冊か書籍を読んでみたのですが、この開発手法が理解できません。 Perlのモジュールとかを例にあげて、分かりやすく説明をお願いします。 また、参考サイトなどあれは、教えて下さい。

    • ベストアンサー
    • Perl
  • オブジェクト指向プログラミング

    大学の情報システムの授業で、様々なパワーポイントを作って発表しています。 現在オブジェクト指向プログラミングについてのパワーポイントを作成中なのですが、私自身あまり良く理解出来ていないためなかなか進みません。 それに関連した例などが載っている分かりやすいサイト等がありましたら教えて下さい。 また、説明して下さる方もいましたら是非! よろしくお願いします。

  • オブジェクト指向の本当の便利な点。

    オブジェクト指向の特徴は、ある程度分かりました。 が、個人で小さなソフトを作り、できるだけ自分でプログラムを作りたいため、オブジェクト指向の利点が今ひとつ分かりません。 PHPでは、構造化でできるだけグローバル変数を減らし、関数内でも関数名+変数名という変数名にしていたので、変数の名前が重複すると言ったこともなかったし。 関数名+でない場合も、関数内では不必要な変数は値を解放していたし。 過去の資産も関数を再利用する事もよくありましたし、継承のような事もしていました。 オブジェクト指向の便利さは分かるのですが、どうも実感できないというか、その便利さを持て余しているというか。 構造化プログラミングでも、さほど問題ないし。 delphiなので、JAVAのようにオブジェクト指向(クラス)が必須という訳でもないし。 逆にクラスを作ってしまうと、メモリーから解放しないといけないので、それが少し怖いです。 で、オブジェクト指向の利点をあげるとしたら何ですか? 可能なら、上位から3つくらいを詳しく書いてください。 ソフトは大規模か小規模か、制作者は大勢か少数・個人か、それは構造化プログラミングでは無理な事なのか? オブジェクト指向の利点や特徴は、分かるのですがピンとこないというか、実感できないというか・・・。

  • オブジェクト指向Perlの勉強の仕方について

    今までPerlで掲示板などを自作した事があるのですが、オブジェクト指向をまったく取り入れていません。 オブジェクト指向でないPerlプログラミングについてはおおよそ理解しているつもりなのですが、 オブジェクト指向Perlについては全く理解できていません。 書籍を探しても、Perlについての書籍は大抵が初心者向けのものか、私にとっては難解なもの(オライリーなど)ばかりで、ちょうどいい程度の書籍が見当たらないのですが、 何かオススメの書籍がありましたらご紹介ください。 ---参考:私が理解している範囲--- 1.Perlプログラミングの基礎 変数、配列、ハッシュなどのデータ型 ループやサブルーチン、ライブラリなどの構造 2.オブジェクト指向について MacromediaFlashのActionScriptがある程度 理解できていますので、 「オブジェクト指向とは何か」 は多少理解しているつもりでいます。 (錯覚かもしれませんが) 3.目的 PerlMagickなどのパッケージを利用したいのだが、 利用方法がわからないため ------------------ 以上、身勝手な質問で恐縮ですが、 よろしくお願いします。

    • ベストアンサー
    • Perl