126

私の知る限り、OOPの教育、言語、ツールに数え切れないほどの数百万または数十億ドルが費やされているにもかかわらず、OOPは開発者の生産性やソフトウェアの信頼性を向上させておらず、開発コストも削減していません。厳密な意味でOOPを使用する人はほとんどいません(LSPなどの原則を順守または理解している人はほとんどいません)。問題のあるドメインをモデル化するために人々が採用するアプローチには、統一性や一貫性がほとんどないようです。多くの場合、このクラスは単にその構文糖衣のために使用されます。レコードタイプの関数を独自の小さな名前空間に配置します。

私はさまざまなアプリケーション向けに大量のコードを作成しました。真の代替可能なサブタイピングがアプリケーションで貴重な役割を果たした場所がありましたが、これらはかなり例外的でした。一般に、「再利用」について話すために多くのリップサービスが提供されますが、実際には、コードの一部が目的どおりに実行されない限り、費用対効果の高い「再利用」はほとんどありません。クラスを適切な方法で拡張できるように設計することは非常に困難であるため、通常、拡張のコストが非常に高いため、「再利用」する価値はありません。

多くの点で、これは私を驚かせません。現実の世界は「OO」ではなく、OOに内在するアイデア、つまりクラスの分類法で物事をモデル化できるという考えは、根本的に欠陥があるように思われます(テーブル、木の切り株、車のボンネットに座ることができます)。 、誰かの膝-しかしそれらの1つではない-椅子)。より抽象的なドメインに移動したとしても、OOモデリングは困難で直感に反し、最終的には役に立たないことがよくあります(円/楕円または正方形/長方形の古典的な例を検討してください)。

だから私はここで何が欠けていますか?OOPの価値はどこにありますか、そしてなぜすべての時間とお金がソフトウェアをより良くすることに失敗したのですか?

4

45 に答える 45

119

現実の世界は「OO」ではなく、OOに内在するアイデア、つまりクラス分類法で物事をモデル化できるという考えは、私には非常に根本的に欠陥があるように思われます。

これは真実であり、他の人々によって観察されていますが(STLの発明者であるStepanovを取り上げてください)、残りはナンセンスです。OOPには欠陥がある可能性があり、特効薬ではありませんが、依存関係を減らすための優れた方法であるため、大規模なアプリケーションがはるかに簡単になります。もちろん、これは「優れた」OOP設計にのみ当てはまります。ずさんなデザインは何の利点もありません。しかし、優れた分離設計は、OOPを使用して非常にうまくモデル化でき、他の手法を使用してモデル化することはできません。

より優れた、より普遍的なモデルがあります(Haskellのタイプモデルが思い浮かびます)が、これらは多くの場合、より複雑で、効率的に実装するのが困難です。OOPは、両極端の間の適切なトレードオフです。

于 2008-08-23T14:48:10.523 に答える
45

OOPは、再利用可能なクラスを作成することではなく、使用可能なクラスを作成することです。

于 2008-08-23T18:04:49.520 に答える
42

多くの場合、このクラスは単にその構文糖衣のために使用されます。レコードタイプの関数を独自の小さな名前空間に配置します。

はい、私はこれもあまりにも普及していると思います。これはオブジェクト指向プログラミングではありません。それはオブジェクトベースのプログラミングとデータ中心のプログラミングです。私のオブジェクト指向言語での10年間の仕事の中で、私は人々が主にオブジェクトベースのプログラミングをしているのを見ます。OBPは、本質的に両方の言葉の中で最悪のものを取得しているため、非常に迅速にIMHOを分解します。1)実証済みの構造化プログラミング方法論に準拠しない手続き型プログラミングと2)実証済みのOOP方法論に準拠しないOOP。

正しく行われたOOPは美しいことです。それは非常に難しい問題を簡単に解決できるようにします、そして初心者には(そこで派手に聞こえようとしないで)、それはほとんど魔法のように見えるかもしれません。そうは言っても、OOPはプログラミング方法論のツールボックスの1つのツールにすぎません。それはすべての方法論であるというわけではありません。たまたま大規模なビジネスアプリケーションに適しています。

OOP言語で作業するほとんどの開発者は、日常的に使用するフレームワークとタイプで正しく行われたOOPの例を利用していますが、彼らはそれを認識していません。いくつかの非常に単純な例を次に示します。ADO.NET、Hibernate / NHibernate、ロギングフレームワーク、さまざまな言語コレクションタイプ、ASP.NETスタック、JSPスタックなど...これらはすべて、コードベースでOOPに大きく依存しているものです。

于 2008-08-23T16:42:45.053 に答える
32

再利用は、OOPの目標であってはなりません-またはそのことに関する他のパラダイム。

再利用は、優れた設計と適切なレベルの抽象化の副作用です。コードは、何か便利なことをすることで再利用を実現しますが、柔軟性を失わせるほどのことはしません。コードがOOであるかどうかは関係ありません。機能するものを再利用し、自分で行うのは簡単ではありません。それは実用主義です。

継承を通じて再利用するための新しい方法としてのOOの考え方には、根本的な欠陥があります。お気づきのように、LSP違反はたくさんあります。代わりに、OOは、問題のあるドメインの複雑さを管理する方法として適切に考えられています。目標は、長期にわたるシステムの保守性です。これを実現するための主要なツールは、パブリックインターフェイスをプライベート実装から分離することです。これにより、コードレビューではなく、コンパイラによって「これは...を使用してのみ変更する必要があります」などのルールを適用できます。

これを使用すると、非常に複雑なシステムを作成および保守できることに同意していただけると確信しています。その中には多くの価値があり、他のパラダイムで行うのは簡単ではありません。

于 2008-09-13T00:14:21.480 に答える
28

宗教的ではありますが、あなたは現代の OOP の状態について過度に厳しい絵を描いていると思います。実際にコスト削減され、大規模なソフトウェア プロジェクトが管理しやすくなったなどと私は主張します。これは、ソフトウェアの混乱という根本的な問題が解決されたことを意味するものではなく、平均的な開発者が OOP の専門家であることを意味するものでもありません。しかし、関数をオブジェクト コンポーネントにモジュール化することで、世界中のスパゲッティ コードの量が確実に減少しました。

頭のてっぺんから何十ものライブラリを思い浮かべることができます。これらのライブラリは美しく再利用でき、計算できないほどの時間とお金を節約しました。

しかし、OOP が時間の無駄であったという点では、言語固有の OOP マッピングを学習するための急激な学習曲線によって悪化した、プログラマーのトレーニングの不足によるものだと思います。OOP を「取得」する人もいれば、取得しない人もいます。

于 2008-08-23T14:45:23.883 に答える
24

オブジェクト指向が、人々が世界について考えるより自然な方法であることを示唆する経験的証拠はありません。プログラミングの心理学の分野では、オブジェクト指向が他のアプローチよりも適しているわけではないことを示すいくつかの研究があります。

オブジェクト指向の表現は、普遍的に使いやすくも使いにくくもないように見えます。

オブジェクト指向メソッドを採用し、開発者にそのようなメソッドを使用するように要求するだけでは十分ではありません。これは、開発者の生産性や開発されたシステムの品質に悪影響を及ぼす可能性があるためです。

これは、Communications of the ACM Oct. 2000 の「On the Usability of OO Representations」からのものです。この記事では、主に OO とプロセス指向のアプローチを比較しています。OO メソッドを使用して作業する人々がどのように「考える」かについては、多くの研究があります (Int. J. of Human-Computer Studies 2001、issue 54、または Human-Computer Interaction 1995、vol. 10 には、OO 研究に関する全体的なテーマがあります)。私が読んだ限りでは、従来の手続き型アプローチよりも適したオブジェクト指向アプローチの自然さを示すものは何もありません。

于 2008-08-24T14:03:42.790 に答える
21

不透明なコンテキストオブジェクト(Win32のHANDLE、CのFILE *)を使用して、2つのよく知られた例を挙げます。HANDLEはカーネルモードバリアの反対側にありますが、実際には取得されません。それよりもはるかにカプセル化されています)手続き型コードにもあります。これがOOPに特有のものであるかどうかを確認するのに苦労しています。

HANDLEs(およびWinAPIの残りの部分)OOPです!CはOOPをあまりサポートしていないため、特別な構文はありませんが、同じ概念を使用していないという意味ではありません。WinAPIは、あらゆる意味でオブジェクト指向フレームワークです。

ほら、これはOOPや代替手法を含むすべての議論の問題です。誰も定義について明確ではなく、誰もが何か他のことについて話しているので、コンセンサスに達することができません。私には時間の無駄のようです。

于 2008-08-23T16:05:08.200 に答える
14

そのプログラミングパラダイム..私たちが単なる人間が問題をより小さく、実行可能な部分に分解しやすくするように設計されています。

あなたがそれが役に立つと思わないならば..それを使わないでください、訓練のためにお金を払わないでください、そして幸せになってください。

一方、私はそれが便利だと思うので、私は:)

于 2008-08-23T15:14:09.337 に答える
14

単純な手続き型プログラミングと比較して、OOPの最初の基本的な信条は、情報の隠蔽とカプセル化の概念です。このアイデアは、インターフェースを実装から分離するクラスの概念につながります。これらは非常に重要な概念であり、プログラム設計を別の方法でより良い方法で考えるためのフレームワークを導入するための基礎です。これらの特性に異議を唱えることはできません。トレードオフはなく、常に物事を調整するためのよりクリーンな方法です。

継承やポリモーフィズムを含むOOPの他の側面も重要ですが、他の人がほのめかしているように、それらは一般的に使いすぎです。すなわち:時々人々は彼らが持つべきであるという理由ではなく、彼らがそうすることができるという理由で継承および/またはポリモーフィズムを使用します。これらは強力な概念であり、非常に便利ですが、賢明に使用する必要があり、OOPの利点を自動的に獲得することはできません。

再利用に関連します。OOPでは再利用が売られすぎていることに同意します。これは、明確に定義されたオブジェクト、通常はよりプリミティブ/ジェネリッククラスの副作用の可能性があり、カプセル化と情報隠蔽の概念の直接的な結果です。明確に定義されたクラスのインターフェースは単純に明確で、ある程度自己文書化されているため、再利用が容易になる可能性があります。

于 2008-08-23T15:43:04.120 に答える
12

OOP の問題は、売られすぎたことです。

Alan Kay が最初に考えたように、これは、生データとすべてグローバルなルーチンを使用するという以前の慣行に代わる優れた方法でした。

その後、一部の経営コンサルタントのタイプがそれに夢中になり、それをソフトウェアの救世主として売り込み、レミングのように、学界と産業界はその後転落しました。

関数型プログラミングなど、他の優れたアイデアが売り過ぎられた後、彼らは今、レミングのように転がっています。

では、どうすればよいでしょうか?たくさんあり、私はこれについて本を書きました。(絶版です - 1 セントももらえませんが、まだコピーを入手できます。) Amazon

私の建設的な答えは、プログラミングを現実世界で物事をモデル化する方法としてではなく、要件をコード化する方法として見ることです。

それは非常に異なり、情報理論に基づいています (誰でも理解できるレベルで)。プログラミングは言語を定義するプロセスと見なすことができ、それを行うスキルは優れたプログラミングに不可欠であると述べています。

これは、ドメイン固有言語 (DSL) の概念を高めます。これは DRY に強く同意します (繰り返さないでください)。コード生成に大きな賛辞を与えます。その結果、最新のアプリケーションで一般的なものよりも大幅に少ないデータ構造を持つソフトウェアが作成されます。

それは、前進する方法は創意工夫にあり、広く受け入れられているアイデアでさえ疑問視されるべきであるという考えを再活性化しようとしています.

于 2008-12-31T13:53:25.920 に答える
11

ハンドル(およびWinAPIの残りの部分)はOOPです!

しかし、彼らはそうですか?それらは継承可能ではなく、確かに代替可能ではなく、明確に定義されたクラスを欠いています...私はそれらが「OOP」にはるかに及ばないと思います。

WinAPIを使用してウィンドウを作成したことがありますか?RegisterClass次に、クラスを定義し( )、そのインスタンスを作成し(CreateWindow)、仮想メソッドを呼び出し(WndProc)、基本クラスのメソッドを呼び出す()などを知っておく必要がありますDefWindowProc。WinAPIは、SmallTalk OOPから命名法を取得し、メソッドを「メッセージ」(ウィンドウメッセージ)と呼びます。

ハンドルは継承できない場合がありますがfinal、Javaには継承できます。クラスが不足しているわけではなく、クラスプレースホルダーです。これが「ハンドル」という言葉の意味です。MFCや.NETWinFormsのようなアーキテクチャを見ると、構文を除いて、WinAPIと大差ないことがすぐにわかります。

于 2008-08-23T16:42:13.230 に答える
11

はい、OOP ですべての問題が解決したわけではありません。申し訳ありません。しかし、私たちはこれらすべての問題を解決する SOA に取り組んでいます。

于 2008-09-17T04:59:06.987 に答える
10

OOPは、GUIの「ウィジェット」などの内部コンピューター構造のプログラミングに適しています。たとえば、SelectListやTextBoxは、「move」や「resize」などの一般的なメソッドを持つItemのサブタイプである可能性があります。

問題は、私たちの90%が、請求書、従業員、仕事、注文などのビジネスコンセプトを扱っているビジネスの世界で働いていることです。「オブジェクト」はより曖昧であり、ビジネスのリエンジニアリングなどによって変更される可能性があるため、これらはOOPにはあまり適して いません。

最悪のケースは、OOがデータベースに熱心に適用される場合です。これにはSQLデータベースへのひどいOOの「拡張」が含まれます。

于 2008-10-23T16:12:15.520 に答える
10

私が経験したプロジェクトのコードと設計をレビューした経験では、多くの開発者がオブジェクト指向モデルを頭の中で適切に概念化していないため、OOP の価値が十分に認識されていません。したがって、彼らは OO 設計でプログラミングせず、非常に多くの場合、クラスをかなりフラットな設計にするトップダウンの手続き型コードを書き続けます。(そもそもそれを「デザイン」と呼べるなら)

ビジネス ニーズに合わせて継承階層を適切に設計するどころか、抽象クラスまたはインターフェイスが何であるかについて同僚がほとんど知らないことを観察するのは非常に恐ろしいことです。

ただし、優れた OO 設計が存在する場合、コードを読んで、コードが直感的なコンポーネント/クラスに自然に収まるのを見るのは、純粋な喜びです。私は常に、会社のさまざまな部門やスタッフの仕事を設計するようなシステム アーキテクチャと設計を認識してきました。すべては、組織/システムを前進させるために必要な相乗効果を生み出し、物事の壮大な計画の中で特定の作業を達成するために存在します。

もちろん、それは残念ながら非常にまれです。世界の美しくデザインされた物理オブジェクトと恐ろしいデザインの物理オブジェクトの比率と同様に、ソフトウェア エンジニアリングとデザインについてもほぼ同じことが言えます。優れたツールを自由に使えるからといって、必ずしも優れた実践や結果が得られるわけではありません。

于 2008-08-24T14:57:43.987 に答える
9

ボンネット、ひざ、木は椅子ではないかもしれませんが、それらはすべて座ることができます。

于 2008-08-25T20:19:07.170 に答える
8

それらの現実世界のものはオブジェクトだと思います

あなたがやる?

請求書にはどのような方法がありますか? あっ、待って。自分で支払うことも、自分で送ることもできず、ベンダーが実際に配達したアイテムと自分自身を比較することもできません。メソッドはまったくありません。それは完全に不活性で機能的ではありません。これは、オブジェクトではなく、レコード型 (必要に応じて構造体) です。

同様に、あなたが言及した他のこと。

何かが実在するからといって、オブジェクト指向の意味でのオブジェクトにはなりません。オブジェクト指向オブジェクトは、状態と動作の独特な結合であり、独自に行動することができます。それは、現実の世界に豊富にあるものではありません。

于 2008-10-02T08:31:38.797 に答える
7

私は過去9年ほどの間OOコードを書いています。メッセージングを使用する以外に、他のアプローチを想像するのは難しいです。私が見る主な利点は、CodingTheWheelが言ったことと完全に一致しています:モジュール化。OOは当然、クリーンなインターフェイスと明確な責任を持つモジュラーコンポーネント(つまり、関心の分離が明確な、疎結合で非常にまとまりのあるコード)からアプリケーションを構築するように導きます。

OOが崩壊するのは、人々が深くネストされたクラス階層を作成するときだと思います。これは複雑さにつながる可能性があります。ただし、共通の機能を基本クラスに分解し、それを他の子孫クラスで再利用することは、非常にエレガントなことです、IMHO!

于 2008-08-23T15:02:58.273 に答える
7

そもそも、観察がやや雑です。私はソフトウェアの生産性に関する数字を持っていませんし、それが上がらないと信じる正当な理由もありません。さらに、OO を乱用する人が多いため、OO がピーナツ バター以来最大のものであったとしても、OO をうまく使用することが必ずしも生産性の向上につながるとは限りません。結局のところ、無能な脳外科医は、まったくないよりも悪い可能性が高いですが、有能な脳外科医は非常に貴重な場合があります.

そうは言っても、オブジェクト指向は物事を整理する別の方法であり、手続き型コードでデータを操作するのではなく、手続き型コードをデータに添付します。OO アプローチがより自然な場合があるため、これは少なくともそれ自体で小さな勝利になるはずです。結局のところ、C++ で手続き型 API を作成することを妨げるものは何もないため、代わりにオブジェクトを提供するオプションにより、言語がより多用途になります。

さらに、OO には非常に優れた機能があります。つまり、古いコードが新しいコードを変更せずに自動的に呼び出すことができるということです。手続き的に物事を管理するコードがあり、以前のものと似ているが同一ではない新しい種類のものを追加した場合、手続き型コードを変更する必要があります。OO システムでは、機能を継承し、好きなものを変更すると、ポリモーフィズムにより新しいコードが自動的に使用されます。これにより、変更の局所性が高まります。これは良いことです。

欠点は、優れた OO は無料ではないということです。適切に学習するには時間と労力が必要です。それは主要な流行語であるため、それを行うためだけにそれを行う人や製品がたくさんあります。優れた手続き型 API ほど優れたクラス インターフェイスを設計するのは簡単ではありません。また、あらゆる種類のエラーが発生しやすくなります (深いクラス階層など)。

必ずしも一般的に優れているとは限らない、別の種類のツールと考えてください。たとえば、ドライバーに加えてハンマー。おそらく最終的には、ねじを打ち込むためにどのレンチを使用すればよいかを知るというソフトウェア エンジニアリングの実践から抜け出すことができるでしょう。

于 2008-12-31T15:24:11.803 に答える
6

私にとって、OOP構文自体には多くの価値があります。多くの場合、実物またはデータ構造を表現しようとするオブジェクトを使用する方が、同じデータで同じことを実行するためにさまざまなフラット(または「フローティング」)関数を使用するよりもはるかに便利です。良いOOPを持つものには、ある種の自然な「流れ」があります。これは、読み取り、書き込み、および長期的な維持を行う方が理にかなっています。

請求書が実際にそれ自体で実行できる機能を備えた「オブジェクト」である必要はありません。オブジェクトインスタンスは、実際にどのタイプのデータが存在するかを知らなくても、データに対して機能を実行するためだけに存在できます。関数「invoice.toJson()」は、「invoice」のデータの種類を知らなくても正常に呼び出すことができます。データベース、XML、CSV、または別のJSONオブジェクトからのものであるかどうかに関係なく、結果はJsonになります。 。手続き型関数を使用すると、突然データについて詳しく知る必要があり、最終的には「xmlToJson()」、「csvToJson()」、「dbToJson()」などの関数になります。最終的には完全に混乱し、基になるデータ型を変更した場合、大きな頭痛の種になります。

OOPのポイントは、実際の実装を抽象化して隠すことです。その目標を達成するには、パブリックインターフェイスを作成する必要があります。そのパブリックインターフェイスを作成しながら作業を簡単にし、物事をドライに保つには、抽象クラス、継承、ポリモーフィズム、デザインパターンなどの概念を使用する必要があります。

したがって、私にとって、OOPの真の最優先の目標は、将来のコードの保守と変更を容易にすることです。しかし、それを超えても、手続き型コードでは不可能だった方法で正しく実行すると、物事を大幅に簡素化できます。それが「実世界」と一致するかどうかは関係ありません。コードを使用したプログラミングは、とにかく実世界のオブジェクトと相互作用しません。OOPは、私の仕事をより簡単かつ迅速にするツールにすぎません。いつでもそのために行きます。

于 2008-12-31T04:22:53.090 に答える
6

@Sean

ただし、共通の機能を基本クラスに分解し、それを他の子孫クラスで再利用することは、非常にエレガントなことです、IMHO!

しかし、「手続き型」開発者はとにかく何十年もそれを行ってきました。構文と用語は異なる場合がありますが、効果は同じです。OOPには、「基本クラスで共通の機能を再利用する」以上のものがあり、それをOOPとして説明するのは難しいと言っても過言ではありません。コードの異なるビットから同じ関数を呼び出すことは、サブプロシージャ自体と同じくらい古い手法です。

于 2008-08-23T15:08:58.460 に答える
6

@Konrad

OOPには欠陥がある可能性があり、特効薬ではありませんが、依存関係を減らすための優れた方法であるため、大規模なアプリケーションがはるかに簡単になります。

それが教義です。この点で、OOPが古い手続き型プログラミングよりも大幅に優れている理由はわかりません。プロシージャコールを行うときはいつでも、実装の詳細から自分自身を隔離しています。

于 2008-08-23T15:11:06.413 に答える
5

@CodingTheWheel

しかし、OOPが時間の無駄である限り、それは、言語固有のOOPマッピングを学習するという急な学習曲線と相まって、プログラマーのトレーニングが不足しているためだと思います。OOPを「取得」する人もいれば、決して取得しない人もいます。

しかし、それが本当に驚くべきことかどうかはわかりません。技術的に適切なアプローチ(LSPは明らかなことです)は使いにくいと思いますが、そのようなアプローチを使用しないと、とにかくコードがもろくなり、拡張できなくなります(もはやそれについて推論できないため)。そして、OOPが私たちを導く直感に反する結果は、人々がそれを受け取らないことを驚くことではないと思います。

さらに重要なことに、ソフトウェアはすでに基本的に普通の人間が確実かつ正確に書くには難しすぎるので、一貫して不十分に教えられ、習得するのが難しいように見える技術を本当に称賛すべきでしょうか?メリットが明確であれば、困難にもかかわらず、忍耐する価値があるかもしれませんが、そうではないようです。

于 2008-08-23T15:06:40.197 に答える
5

@ジェフ

単純な手続き型プログラミングと比較して、OOPの最初の基本的な信条は、情報の隠蔽とカプセル化の概念です。このアイデアは、インターフェースを実装から分離するクラスの概念につながります。

C ++のiostream、またはCのFILE *のどちらが、より隠された実装を持っていますか?

不透明なコンテキストオブジェクト(Win32のHANDLE、CのFILE *)を使用して、2つのよく知られた例を挙げます。HANDLEはカーネルモードバリアの反対側にありますが、実際には取得されません。それよりもはるかにカプセル化されています)手続き型コードにもあります。これがOOPに特有のものであるかどうかを確認するのに苦労しています。

それが、私がメリットを見つけるのに苦労している理由の一部かもしれないと思います。明らかに良い部分はOOPに固有ではありませんが、OOPに固有の部分は明らかに良くありません。(これは、それらが必ずしも悪いということではなく、むしろ、それらが広く適用可能であり、一貫して有益であるという証拠を見たことがないということです)。

于 2008-08-23T15:54:57.743 に答える
5

私が読んだ唯一の開発ブログで、その Joel-On-Software-Founder-of-SO の男によって、私はずっと前に、OO は生産性の向上につながらないことを読みました。自動メモリ管理は行います。涼しい。誰がデータを否定できますか?

私は今でも、関数を使ったプログラミングがすべてをインラインでプログラミングすることであるのと同じように、オブジェクト指向ではないことを信じています。

(そして、GWBasic から始めたので、知っておくべきです。) 関数を使用するようにコードをリファクタリングすると、現在のメソッドにvariable2654なります。 それは呼び出され 、完全に理解するにはそれで十分です。variable3value

関数のないコードがメソッドを含むコードになると、何マイルものコードを削除する必要があります。

コードを真に OO になるようにリファクタリングすると、、、bcq、にZなります。そして、私はキーワードの使用を信じていないので、何マイルものコードを削除する必要があります。実際には、 を使用してもそれを行うことができます。thisthisthisthisthisthis



オブジェクト指向は自然な比喩ではないと思います。

言語も自然な比喩だとは思いませんし、ファウラーの「におい」が「このコードは味が悪い」と言うよりも優れているとは思いません。そうは言っても、オブジェクト指向は自然なメタファーに関するものではなく、オブジェクトが飛び出すだけだと考える人は基本的に要点を見失っていると思います。オブジェクト ユニバースを定義すると、オブジェクト ユニバースが改善された結果、コードが短くなり、理解しやすくなり、動作が改善されます。または、これらすべて (およびいくつかの基準を忘れています)。顧客やドメインの自然なオブジェクトをプログラミング オブジェクトとして使用する人々には、宇宙を再定義する力が欠けていると思います。

たとえば、航空会社の予約システムを実行する場合、予約と呼ぶものは、法的/ビジネス上の予約とはまったく一致しない場合があります。



基本的な概念のいくつかは本当にクールなツールです

ほとんどの人は、「ハンマーを持っていると、すべて釘になる」ということを誇張していると思います。コイン/ミラーの反対側も同じように真実だと思います: ポリモーフィズム/継承のようなガジェットを持っていると、手袋/靴下/コンタクトレンズのようにフィットする用途が見つかり始めます. OO のツールは非常に強力です。単一継承は、人々が夢中にならないようにするために絶対に必要であり、私自身の複数継承ソフトウェアは耐えられません。



OOPのポイントは何ですか?

非常に大規模なコード ベースを処理するための優れた方法だと思います。コードを整理および再編成し、それを行うための言語を (使用しているプログラミング言語を超えて) 提供し、非常に自然でわかりやすい方法でコードをモジュール化できると思います。

OOP は大多数の開発者に誤解される運命にあります

これは、人生と同じように目を見張るようなプロセスだからです。OO については、経験を積むにつれて理解が深まり、賢くなるにつれて特定のパターンを避けたり、他のパターンを採用したりし始めます。最良の例の 1 つは、制御しないクラスの継承の使用をやめ、代わりにFacadeパターンを好むことです。



小論文・質問について

私はあなたが正しいと言いたかった。ほとんどの場合、再利用可能性は夢物語です。そのトピックに関する Anders Hejilsberg からの引用を次に示します (すばらしい)ここから:

初心者のプログラマーにカレンダー コントロールを作成するように依頼すると、彼らはしばしば「ああ、世界最高のカレンダー コントロールを作成するつもりだ! カレンダーの種類に関してポリモーフィックになるだろう.そしてマンガー、そしてこれ、あれ、そしてその他。」カレンダー アプリケーションを 2 か月以内に出荷する必要があります。彼らは、このすべてのインフラストラクチャをコントロールに配置し、その上にくだらないカレンダー アプリケーションを 2 日間かけて作成します。彼らは、「アプリケーションの次のバージョンでは、もっと多くのことができるようになるだろう」と考えるでしょう。

しかし、彼らの抽象的なデザインの他の具体化を実際にどのように実装するかを考え始めると、彼らのデザインが完全に間違っていることが判明します。そして今、彼らは自分たちを追い詰めてしまい、すべてを捨てなければなりません。私はそれを何度も見てきました。私はミニマリストであることを強く信じています。一般的な問題を実際に解決しようとしている場合を除き、特定の問題を解決するためのフレームワークを導入しようとしないでください。そのフレームワークがどのように見えるべきかわからないからです。

于 2008-12-31T01:11:46.237 に答える
4

WinAPIを使用してウィンドウを作成したことがありますか?

覚えておくよりも何度も。

次に、クラスを定義し(RegisterClass)、そのインスタンスを作成し(CreateWindow)、仮想メソッドを呼び出し(WndProc)、基本クラスのメソッドを呼び出す(DefWindowProc)ことなどを知っておく必要があります。WinAPIは、SmallTalk OOPから命名法を取得し、メソッドを「メッセージ」(ウィンドウメッセージ)と呼びます。

そうすれば、それ自体がメッセージディスパッチを行わないこともわかります。これは大きなギャップです。また、くだらないサブクラス化もあります。

ハンドルは継承できない場合がありますが、Javaにはfinalがあります。クラスが不足しているわけではなく、クラスのプレースホルダーです。これが「ハンドル」という言葉の意味です。MFCや.NETWinFormsのようなアーキテクチャを見ると、構文を除いて、WinAPIと大差ないことがすぐにわかります。

それらは、インターフェースまたは実装のいずれにおいても継承可能ではなく、最小限の代替可能であり、手続き型コーダーが永遠に行ってきたことと実質的に違いはありません。

これは本当にそれですか?OOPの最高の部分はただ...従来の手続き型コードですか? それは大したことですか?

于 2008-08-23T17:13:26.993 に答える
4

OOP の最も有益な性質は、データの隠蔽/管理だと思います。ただし、OOP が誤用されている例はたくさんあり、ここで混乱が生じると思います。

何かをオブジェクトにできるからといって、そうすべきだというわけではありません。ただし、そうすることでコードがより整理され、読みやすくなる場合は、間違いなくそうする必要があります。

OOP が非常に役立つ実用的な例として、私が Web サイトで使用している「製品」クラスとオブジェクトがあります。すべてのページは製品であり、すべての製品には他の製品への参照があるため、データがどの製品を参照しているかについて非常に混乱する可能性があります. この「strURL」変数は、現在のページ、ホームページ、または統計ページへのリンクですか? 確かに、同じ情報を参照するあらゆる種類の異なる変数を作成できますが、proCurrentPage->strURL の方が (開発者にとって) 理解しやすいです。

さらに、これらのページに関数を添付すると、はるかにクリーンになります。proCurrentPage->CleanCache(); を実行できます。proDisplayItem->RenderPromo(); が続きます。これらの関数を呼び出して、現在のデータが利用可能であると仮定した場合、どのような悪が発生するかは誰にもわかりません。また、これらの関数に正しい変数を渡さなければならない場合、さまざまな製品にさまざまな変数を配置するという問題に戻ります。

代わりに、オブジェクトを使用することで、すべての製品データと関数が素晴らしく、クリーンで理解しやすくなっています。

でも。OOP の大きな問題は、すべてが OOP であるべきだと誰かが信じている場合です。これは多くの問題を引き起こします。データベースに 88 個のテーブルがあります。私は約 6 クラスしか持っていませんが、おそらく約 10 クラスが必要です。88 クラスは絶対に必要ありません。ほとんどの場合、これらのテーブルに直接アクセスすることは、私が使用している状況では完全に理解できます.OOPは、実際に起こっていることのコア機能に到達することをより困難/退屈にします.

私は、有用で実用的な手続き型のオブジェクトのハイブリッドモデルが最も効果的なコーディング方法であると信じています。人々が他の方法を犠牲にして、ある方法を使用することを提唱するこれらすべての宗教戦争が私たちにあるのは残念です. どちらも良いですし、どちらにもそれぞれの場所があります。ほとんどの場合、大規模なプロジェクトごとに両方の方法が使用されます (一部の小規模なプロジェクトでは、1 つのオブジェクトまたはいくつかの手順で十分な場合があります)。

于 2008-09-15T21:27:39.700 に答える
4

InSciTek Jeffの回答に完全に同意します。次の改良点を追加します。

  • 情報の隠蔽とカプセル化: 保守可能なコードにとって重要です。どのプログラミング言語でも注意して実行できます。オブジェクト指向機能は必要ありませんが、これを行うと、コードがわずかにオブジェクト指向に似たものになります。
  • 継承: これらすべての OO is-a-kind-ofおよびcontains-a関係が完全に適合する 1 つの重要なアプリケーション ドメインがあります: グラフィカル ユーザー インターフェイスです。OO 言語サポートなしで GUI を構築しようとすると、とにかく OO のような機能を構築することになり、言語サポートなしではより難しく、エラーが発生しやすくなります。たとえば、Glade (最近) と X11 Xt (歴史的に) です。

オブジェクト指向機能 (特に深くネストされた抽象階層) を使用しても、意味がない場合は無意味です。しかし、一部のアプリケーション ドメインについては、実際にはポイントがあります。

于 2008-09-11T14:42:05.310 に答える
3

読みやすさほど再利用は気にしません。後者は、コードの変更が容易であることを意味します。それだけでも、ソフトウェア構築の技術において金の価値があります。

OO は、プログラムを読みやすくするための非常に効果的な方法です。再利用するかしないか。

于 2008-12-31T13:30:38.837 に答える
2

これは、変数をそれらと相互作用する関数/メソッド/サブルーチンと一緒にグループ化するための唯一の言語移植可能な方法論です。

于 2008-12-31T03:00:31.540 に答える
2

1980 年代半ばに C/Unix (非 OOP) で始まり、1990 年に C++ (OOP) に移行し、1996 年頃に Java (OOP) に移行した私の経験から、OOP が生産性、保守性、および堅牢性を大幅に向上させることを発見しました。私が以前に取り組んでいた大規模な非 OOP プログラムと比較して。

私が観察した主なことは、私が取り組んだ非 OOP アプリケーションでは、複雑さがアプリケーションの洗練度に関して指数関数的に増加するように見えたのに対し、私が取り組んだ OOP アプリケーションでは複雑さがはるかに直線的であるように見えたことです。アプリケーションの洗練度との関係。

言い換えれば、適切に設計された OOP アプリケーションを使用すると、大規模な非 OOP アプリケーションで得られるような「このアプリのソース コードが制御不能になっている」という感覚を得ることはありません。

OOP 開発者として欠かすことのできないもう 1 つのことは、アプリケーションの問題領域に存在する現実世界のエンティティをモデル化するコードを作成する方法です。オブジェクトは独自の生命を持ちます - 構造体 (C) やレコード (Pascal) が OOP 以外の古き良き時代に行ったことをはるかに超えています。

1 つの規定は、OOP プロジェクトのチーフ アーキテクトは自分が何をしているかを理解している必要があり、通常、実際に実装するよりも、設計を正しく行うために多くの時間を費やす必要があるということですが、「事前に物事を考える」ことの見返りは本当に驚くべきものです。 . 再利用の機会や非常にクールなデザインの最適化が明るみに出て、オフィスで大騒ぎしたり、タッチダウンしたりします... わかりました、オフィスの他の人には少し奇妙に見えるかもしれませんが、そのような熱意は非日常では決して起こりませんでしたOOP日:)

私はかなりひどい OOP コードを見たことがありますが、おそらくそれがあなたが経験したことで、質問をするようになったのかもしれません。90 年代半ばに請負業者だった私は、「OO」の設計は、クラスとは何かを知っているが、それ以上のことは知らない誰かによってすでに開始されていたことによく気づきました。それは非常につらい経験であり、仕事を始めてから最初の数か月は、非常に異なる「OO」の考え方でチームを教育する必要があることがよくありました。全員の脳が再配線されて初めて、チームとして素晴らしいものを作成できるようになりました。

多くの人は、「脳の再配線」プロセスが難しすぎたり、苦痛だったり、労力がかかりすぎたりして、OOP を否定することに人生を費やしています。私のような人が見栄えがするのは、「なんと、X ドルでそれを行うことができ、2 か月で準備が整い、保守可能なコード ベースが提供されます!!! うわー、今日から始められますか?」

于 2010-02-03T05:26:29.563 に答える
2

OOP のポイントは、問題の解決策をコードで記述し、マシンや人に伝えるための別の手段をプログラマーに提供することです。その中で最も重要な部分は、人々とのコミュニケーションです。OOP を使用すると、プログラマーは、OO 言語で適用される規則を使用して、コード内で何を意味するかを宣言できます。

このトピックに関する多くの議論とは対照的に、OOP および OO の概念は、C などの非 OOP 言語のコードを含むすべてのコード全体に浸透しています。

オブジェクト指向を言語に組み込むことは、プログラマーに別の表現手段を提供するだけです。

コードを書くことの最大の部分は、機械とのコミュニケーションではありません。その部分は簡単です。最大の部分は、人間のプログラマーとのコミュニケーションです。

于 2008-12-17T23:12:32.653 に答える
2

「現実世界は『○○』じゃない」

本当に?私の世界は物でいっぱいです。私は今1つを使用しています。ソフトウェアの「オブジェクト」が実際のオブジェクトをモデル化することは、それほど悪いことではないと思います。

概念的なもの (Windows など、現実世界のウィンドウではなく、コンピューター モニターのディスプレイ パネル) の OO 設計には、多くの場合、多くの要望が残されています。しかし、請求書、出荷注文、保険請求などの現実世界のものについては、それらの現実世界のものはオブジェクトだと思います. 机の上にスタックがあるので、それらは本物に違いありません。

于 2008-10-01T08:08:59.030 に答える
1

「実際の[情報アーキテクチャ]がなくても、それを体験したり認識したりしないという意味ではありません。禅仏教徒は、実際の「自己」はないと言いますが、それでも子供たちに名前を付けます。」-アンドリュー・ヒントン

于 2008-08-23T15:11:50.920 に答える
1

ハンドル(およびWinAPIの残りの部分)はOOPです!

しかし、彼らはそうですか?それらは継承可能ではなく、確かに代替可能ではなく、明確に定義されたクラスを欠いています...私はそれらが「OOP」にはるかに及ばないと思います。

于 2008-08-23T16:31:57.497 に答える
1

私にとって、OOPの価値は、スコープを縮小し、状態を動作から分離することです。スコープが小さいほど、コードが理解しやすくなります。

これはほとんどの言語で実行できます。これを実現するために必要なのは、状態がメソッド呼び出しをビヘイビアーに委任する方法と、ビヘイビアーが呼び出しを親ビヘイビアーにさらに委任する方法です。

クラスのセットが効果的な方法でドメインをモデル化するようにするために、魔法の方法はありません。ピアノのように、私たちは練習しなければなりません。OOPは抽象的なツールであり、コードをより簡単に構築するのに役立ちますが、アプリのドメインを考えて分析することはできません。

私にとってうまくいくのは、ほとんどのコードの重複を避けながら、できるだけ長くドメインの近くにとどまることです。

于 2008-10-23T15:58:49.383 に答える
1

私は、OOPが構文糖衣ベース(カプセル化、演算子のオーバーロード、型チェック)だけでほとんど役立つことを知っています。OOPのメリットについては…わかりません。手続き的なものより悪いとは思いません。

軽い面では、私のOOP講師は、OOPが重要であると述べました。そうしないと、「コードのループが多すぎる」からです。うん。時々、私が紙1枚あたり500ドルを支払うのは気のめいることです。:(

于 2008-08-29T01:30:38.800 に答える
1

OOPは、インターフェースを実装から分離するのに役立ちます。オブジェクト指向設計の恩恵を受けるために、その言語でのOOPサポートは必要ありません。

OOPが非常に役立った1つの小さな例:

UNIX仮想ファイルシステム(VFS)レイヤーは、C ++仮想テーブルディスパッチによく似た、関数ポインターのテーブルを使用した統一されたインターフェイス(オープン/読み取り/書き込み)を提供します。

クライアントは、ローカルファイルシステム、リモートネットワークファイルシステム(NFS)、または(現在の)偽のファイルシステム(/ procなど)のいずれと通信しているかに関係なく、同じ一連の呼び出しを使用します。

元のSunの論文を参照してください:Vnodes:SunUNIXでの複数のファイルシステムタイプのアーキテクチャ

于 2008-12-31T12:40:22.073 に答える
1

ボンネット、ひざ、木は椅子ではないかもしれませんが、それらはすべて座ることができます。

はい、ただし事後的にのみです。誰かが座ったので、それらは ISittable です。

于 2008-08-27T20:11:52.817 に答える
1

これは古い投稿であるため、これについてはすでに多くの回答がありますが、私はチャイムを鳴らすと思いました.

サブタイピングとポリモーフィズムに入る「クラス分類法」について少し言及しました。これはすべて、全盛期に OOP の特効薬と見なされていた継承を中心に展開しています。今日では、多くの OOP を行うショップの間でも、継承と大規模なクラス階層は実際には推奨されていません。これは、カプセル化、疎結合、結合などの OOP の他の原則が、継承よりもはるかに有用であることがわかっているためです。コードの再利用ではなく、疎結合が OO の理由であるとさえ言えます。コードの再利用は通常、メソッド/関数レベルで発生します。さまざまな状況でクラスを再利用することもありますが、それほど頻繁ではありません。ただし、疎結合はシステムの編成にかなり役立ちます。各オブジェクトには独自のスコープがあり、オブジェクト内のデータは「アクセサ メソッドまたはプロパティ以外で操作することはできません。各オブジェクトは 1 つの単純な処理を実行し、単純なインターフェイスを介して他のオブジェクトと通信する必要があります。この一握りの原則は、コードの可読性を高め、バグを分離し、1 つのことを変更するために多くの異なる場所で多くの変更を行う必要がないようにするのに役立ちます。オブジェクトが密接に絡み合っていない場合は、他のオブジェクトに影響を与えずに 1 つを変更できます。これは私にとって大きなメリットでした。継承は時々しか役に立ちません。他の人に影響を与えることなく、1 つを変更できます。これは私にとって大きなメリットでした。継承は時々しか役に立ちません。他の人に影響を与えることなく、1 つを変更できます。これは私にとって大きなメリットでした。継承は時々しか役に立ちません。

コードの再利用は依然として重要であり、同じコードをコピーして貼り付けたり、書き直したりする場合、単純な古い手続き型、構造化、または関数型プログラミングであっても、それは悪い習慣です。作業の重複、メンテナンスの増加、バグの増加により、実際にはコストが増加します。

于 2009-10-20T15:54:57.463 に答える
1

関数型プログラミングについて、今から 10 年後も同じことを言うでしょうか?

于 2008-12-31T13:19:12.557 に答える
1

現実世界は「○○」ではない。現実の世界は、賢明な断片から大部分が構成されているわけではありません。代わりに、無秩序に動く粒子から作られています。地球は粒子のスープです。それでも人は鳥、木、空、地面、森、池を見る。オブジェクト指向は、プログラム コンポーネントの抽象化に関するものです。プログラム以外のものをモデル化するための OO について考えるのは根本的に間違っています。

プログラマーをより賢くすることができず、ソフトウェアに対する人々の考え方を変えることもできなかったので、すべてのお金と時間をかけてソフトウェアを改善することができませんでした。あなたが使用する意味での「OOP」は、馬鹿からお金を引き出すために使用される流行語です. はい、「OOP」の教育とツールにお金をかけた人はばかです。デマに陥りがちな人は、馬鹿になりがちです。

「OOP」の価値は、同じプログラム内での抽象化とコードの再利用です。OOP は、命令型プログラムで使用するためのものです。

組み立てルーチンから立ち上がる場合。アセンブリは、ラベルと命令から構成されるペアの順序付けられたシーケンスです。アセンブリ コードは「パーティクル スープ」に似ています。これで、サブルーチンに移動できます。サブルーチンは、その label:instruction -soup からラベルを選択し、残りのラベルをサブルーチン内に隠します。効果コードがより抽象的になり、名前空間がよりクリーンなままになります。

さて、サブルーチンが何をするかを考えてみると... 数十年前、人々は、サブルーチンは引数に取り組むときに最高の状態になると考えていました。そのため、各オブジェクトに独自のプロトコルを与えるようになりました。プロトコルには label:procedure -pairs が含まれます。現在は selector:method -pairs と呼ばれています。プロシージャーは他のプロシージャーに直接バインドされなくなり、「レイト バインディング」という用語が説明されました。プロトコルからの履歴を保持する (継承) と共に、これはスモールトークの「オブジェクト指向」を形成しました。

レイト バインディング メカニズムが機能しなくなり、継承の意味を忘れてしまいました。そして、あなたはまだそこに何が欠けているのか疑問に思っています. 「OOP の価値はどこにあるのか、なぜこれまで時間とお金をかけてソフトウェアを改善できなかったのか?」- お尻に詰め込んだと思います。大腸内視鏡検査を試みると、それらが見つかります。

于 2008-12-31T14:14:13.817 に答える
0

OOPにより、コストが削減され、効率が向上しました。

従来のASP/VBScriptからC#にジャンプしたとき、OOPのおかげで生産性が大幅に向上したことに気づきました。

于 2008-08-23T15:57:02.963 に答える
0

InSciTek Jeff に同意します。オブジェクト指向を純粋な意味で使用しない場合でも、カプセル化理論は潜在的な構造の複雑さを軽減するのに役立ちます: http://www.edmundkirwan.com

@ DrPizza

手続き型プログラミングがカプセル化の利点を同程度に利用しているなら、それでいいのです!

于 2008-10-28T20:42:56.790 に答える
0

現実世界は OO ではないかもしれませんが、人々は論理よりも類推 (抽象化) を使って学習したり考えたりする傾向があります。

OOP はコンピュータ向けではなく、類推なしに複雑なシステムを理解するのが苦手なプログラマ向けです。OOP の主な目的は、抽象化を使用してコードをより適切に編成することであると信じています。そのため、プログラマーは、他の部分の知識がなくても、システムの特定の部分またはシステム全体が、自分がなりたいレベルで何をしているのかを簡単に理解できます。

コードを抽象化して整理するには、言語にカプセル化、継承、ポリモーフィズムも必要です。そして、SOLID OOP の原則と設計パターンは、この組織でより良い仕事をするために登場します。しかし、OOP の全体的なポイントは抽象化だと思います。

于 2014-08-14T17:09:29.423 に答える
0

OOP はインスタンス化に関するものです...同じものを何度も再インスタンス化し、そのアクティビティの分類をわずかに変えたいとします。共有活動とは、共有クラスを意味します。

そのように考えたくない場合は、OOP を実行しないでください。それは間違いなくパスカルの後にそれについて考え始めるために心をひねります。したがって、怒っているプログラマーです。

インスタンス化ロボットを最後の違いまで詳細に説明し、同じことを一度も繰り返さないでください。

分類の違いごとに 1 つのラベル/クラスしかありません (すべての異なるものではありません!)。これが OOP の力です...そして、それが AI の超ニューラル ネットワークに似ており、異なるものの名​​前が尽きることはありません。名前を付けると、全体の分布に依存するためです。

-マグナス W.

于 2014-09-28T09:38:09.307 に答える