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


126

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

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

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

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


11
アナロジーは、意図する「ユースケース」に対して抽象化が高すぎる。テーブル、木の切り株、ボンネット、誰かの膝は、分子、原子、陽子、中性子、電子の組成物であり、重力の力でお尻が静止するのに十分な表面積を形成します。
icelava 2008

38
この同じスレッドが何回起動されても、常に多くの関心が集まります(通常、ここでは重複が許容されないという事実にもかかわらず)。そしてもちろん、選ばれた答えは常に質問者の最初の意見に同意するものです。
TM。

4
OOPの問題は、OOPをコンテキストに配置できないことです。すべての目的ではなく、いくつかの目的に最適です。それは素晴らしいツールです。お粗末な福音です。
Mike Dunlavey、2008

16
申し訳ありませんが、どのような言語でもプログラミングしたことがないという気持ちを揺さぶることはできません。その理由は次のとおりです。OOPは、すべての最新環境(Java、.NET、Python、Ruby-いくつかの主流のものに名前を付ける)のベースコンポーネントライブラリの操作のベースです。これらのベースライブラリはすべて毎日再利用されているので、それが重要でない場合、何ができるのかわかりません。ですから、ここで誤解しないでください。ただし、事実である場合はコードを再利用してください。私はこれが決して不快に聞こえるようにしたくありません-ここでポイントを作るだけです。
Matthias Hryniszak 09

2
@George Jempty:「MicrosoftがAPI戦争に負けた方法」(joelonsoftware.com/articles/APIWar.html)のJoel Spolsky でした。一節の見出しは「Automatic Transmissions Win the Day」です。
GodsBoss 2010

回答:


24

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

オブジェクト指向の表現は、普段より使いやすく、または使いにくいようには見えません。

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

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


18
正常に動作します。それができないことは、悪いコーダーに良いコードを書かせることです。定期的な色合いがあり、そのためそれに対して叫ぶ。
混乱

6
@melaos:概要は真ん中です。OOPはツールキットの1つのツールであり、唯一のものではなく、トレーニング、経験、および判断に代わるものはありません。
Mike Dunlavey、2008

44
反対を支持するより高い評価の質問があるとしても、誰かが「質問」を投稿してポイントを主張し、そのポイントを支持する最初の回答を受け入れるとき、私はそれは一種の面白いと思います。人間性はかっこいいです。
ビルK

3
@melaos、(少なくともこれらの記事の)要約は、OOが人々にとって自然な考え方であることを示唆するものはなく、したがって、プログラムを構築する他の方法よりも本質的に優れているわけではありません。
スベン

6
@Bill K:OOの方が「優れている」べきであるという単なる手振りではなく、引用を提供した数少ない回答の1つでした。参考文献が、OOが特定の改善や特定の利点ではないという考えを支持し、それゆえ私の元の立場を支持するのであれば、なぜそれを無視すべきかわかりません。私のOPに対抗する同様の参照を提供できますか?
DrPizza 2009年

119

現実の世界は「OO」ではなく、OOに内在する考え(クラス分類法でモデル化できる)は、根本的に欠陥があるように思えます

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

はるかに優れた、より普遍的なモデルがあります(Haskellの型モデルが頭に浮かびます)が、これらはしばしばより複雑であり、効率的に実装することが困難です。OOPは両極端の間の適切なトレードオフです。


10
これが質問と承認された回答の合計よりも賛成票が多いのは興味深いことです。
ブラッドギルバート

15
Haskellの型システムはOOよりも直感的です。
axblount

4
@Konrad:「しかし、それは大規模なアプリケーションをはるかに簡単にします」-うーん、私はそれが本当かどうかわかりません。あるものを変更することが別のものを壊すのではなく、より簡単にするという意味で、それらはより保守しやすくなりますか?それは飲み込むべきものです...
ミッチウィート

2
@BradGilbert:もちろん、質問者は最初の質問の意見と完全に一致する回答を選択しました。どちらが問題を提起しますか、あなたがすでに答えを決めているのなら、なぜわざわざ質問をするのですか?
TM。

2
@Mitch:ある種のオブジェクト指向がないと(今日の時点では)大規模なアプリケーションを記述できないと私主張します。大規模な場合は、1Mを超えるLOCです。
Konrad Rudolph、

45

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


7
良いですね!そして、そうです。
トゥーンクライテ2008

1
けっこうだ。しかし、それは「車輪の再発明」の問題を解決しません。これは、正直に言うとソフトウェア開発において深刻な問題です。欠陥を探すためにN組の目を持つ1つのライブラリーを持つ代わりに、1組の目を持つNライブラリーがあります。そう。再利用を開始する前に作成できるクラスがたくさんあります。そして、私の教育を受けた意見のOOPは、まさにその領域で根本的に欠陥があります-コードの再利用。データを非表示にし、メソッドと「結合」して、効果的にアクセスできない、またはほとんど相互運用できないようにします。
AMN

42

たいていの場合、クラスは単にその構文上の砂糖のために使用されます。レコード型の関数を独自の小さな名前空間に配置します。

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

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

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


32

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

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

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

これを使用すると、あなたが同意し、私たちが非常に複雑なシステムを作成して維持できるようになると確信しています。その中には多くの価値があり、他のパラダイムでそれを行うのは容易ではありません。


3
再利用とOOが別々の関心事であることに当てはまります。
Dan Rosenstark、2008

28

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

私の頭の上の数十のライブラリは、美しく再利用でき、計算することのできない時間とお金を節約できます。

しかし、OOPが時間の浪費であった限り、それは、言語固有のOOPマッピングを学習するという急な学習曲線によって悪化する、プログラマーのトレーニングの欠如が原因であると私は言います。OOPを「取得」する人もいれば、絶対に取得しない人もいます。


2
私はあなたに2000ポイントを超えて投げる賛成票を与えました-うまくいけばそれは固執するでしょう。:P
Jason Bunting

5
OOPが効果的に教えられることはまれです。
Jon W

あなたの答えは、それが理にかなっているかどうか尋ねられたとき、アジャイル/スクラムトレーナーによって与えられたものとよく似ています-「それを正しく行うと、それは非常に役立ちます。「再利用可能」や「保守可能」などの単語を使い分けるのは簡単ですが、実際のコードでこれらの品質を定量化することは簡単ではなく、優れたOOPを書く方法を説明するレシピもありません(そうしようとする何千もの本にも関わらず)。 。また、表面的にはハードウェアを無視するという悪い癖があります。これは、時期尚早な最適化を回避するという祭壇での恐ろしいパフォーマンスにつながります。
トム

21

2つのよく知られた例を挙げると、不透明なコンテキストオブジェクト(Win32のハンドル、CのFILE * s)の使用が考えられます。それよりもはるかにカプセル化されています)手続き型コードにもあります。これがOOPに特有のものであるかどうかを確認するのに苦労しています。

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

これは、OOPまたは代替手法に関するすべての個別の議論の問題です。誰もその定義について明確ではなく、誰もが何か他のことについて話しているため、合意に達することができません。私にとっては時間の無駄のようです。


1
非常によく似たものを投稿しようとしていました。
ブラッドギルバート

特別な構文がなくてもOOPの概念を使用できることに同意しますが、一方で、WinAPIがOOPの概念の良い例であるとは思いません。
Lena Schimmel、

14

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

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

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


14

単純な手続き型プログラミングに比べて、OOPの最初の基本的な信条は、情報の隠蔽とカプセル化の概念です。このアイデアは、実装からインターフェースを分離するクラスの概念につながります。これらは非常に重要な概念であり、プログラム設計を別の方法で、より良い(私は)方法で考えるためのフレームワークを配置するための基礎です。これらのプロパティに対して実際に異議を唱えることはできません-トレードオフは発生せず、常に物事をモジュール化するためのよりクリーンな方法です。

継承やポリモーフィズムなど、OOPの他の側面も重要ですが、他の人が言及したように、これらは一般的に過剰に使用されています。つまり、継承や多態性を使用することがあるからではなく、使用する必要があるからです。これらは強力な概念であり、非常に便利ですが、賢く使用する必要があり、OOPの自動的な利点ではありません。

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


1
再利用は、ソフトウェア開発者にとっての目標の1つです。オブジェクト指向であろうと機能的であろうと、使用するパラダイムに関係なく、そうではありませんか。これは、ソフトウェアに対して行われる絶え間なく変化する要件と矛盾し、問題は柔軟な設計を行うことの1つであるようです。
ジオグリフ2009年

「インターフェースと実装を分離するクラスの概念」---インターフェースはインターフェースであり、クラスは実装であると思いましたか?たぶん、私はあまりにもプロセス指向の思想家なのかもしれませんが、私はそれが多態性、つまり使用における均一性を伴うコードの差異であることを理解しています。それがOOPのキッカーです。「C関数の束」は、「Javaクラス」と同様に、インターフェースを実装から分離することを理解しています。たぶん私はすべて間違っていますか?
JonasKölker、2009年

2
@Jonas-あなたの「C関数の束」に対して---実装からインターフェースを分離できることに同意し、その時点でそれはOOPになり始めています。例では、APIが上で動作し、あなたは基本的に(APIは構造上不透明で動作する場合は特に)カプセル化を作成したことをCの構造体を定義するために続けて...そして、それは本当にCでOOPされている場合
トールジェフ

12

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

Alan Kayが最初にそれを考案したように、これは、生データと全グローバルルーチンを使用する従来の方法の優れた代替手段でした。

その後、いくつかの経営コンサルタントのタイプがそれにラッチし、ソフトウェアのメシアとしてそれを販売しました、そして、レミングのような、学界と産業はそれの後につまずきました。

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

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

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

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

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

それは、進歩は発明性にあるという考えを再活性化することを目指しており、十分に受け入れられている考えでさえ疑問を呈するべきです。


涼しい。この本は絶版になっているので、PDFを提供したくありません。AmazonがSLOWLYをアルゼンチンに送信...
Dan Rosenstark 2008

私は、プロセスの初期段階でそのどこかを疑い、いくつかの良いコーダーは、彼らがOOPで何ができるかについてrhapsodicワックス、と誰かがそれを耳にし、その意味と思った誰もが可能性があり、同様に行うだろう両方。
混乱

@ダニエル:良い提案。私はそれに取り組み、それをブログスポットに添付できるかどうかを確認します。それは'94年にあったので少し古臭いのがわかりますが、原則は変わっていません。
マイクダンレイビー、2009年

1
@Mike Dunlavey拝啓、インターネットを介して本を[少なくとも部分的に]読む/入手する機会があるかどうかを知る@yarの好奇心をサポートしてもらえますか?効果的なソフトウェア[コンポーネント]仕様/提案/開発の方法が[最近認識した]ものとよく似ているので、私は学びたい、または教えたい(よく、書かれているが、あいまいな主流のOO本)。前もって感謝します[そしてロシアから乾杯:)]。
mlvljr 2010

1
@mlvljr:OK。最も簡単な方法は、それをスキャンして大きなPDFファイルを作成することです。数日中に届くかどうか確認します。[モスクワでの最近の出来事に心からお悔やみ申し上げます。また、水浸しのマサチューセッツからの歓声]もお忘れなく。
Mike Dunlavey、2010

11

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

でも彼らは?それらは継承可能ではなく、それらは確かに代用可能ではなく、明確に定義されたクラスを欠いています...それらは "OOP"には程遠いと思います。

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

ハンドルは継承できない可能性がありますがfinal、Javaにはあります。彼らは、クラスに欠けていないです何語「ハンドル」の手段です:クラスのプレースホルダ。MFCや.NET WinFormsなどのアーキテクチャを見ると、構文を除いて、WinAPIと何も変わらないことがすぐにわかります。


WINAPIはOOPではありません。それは、拡張可能な手続き型コードを書く方法を示すだけです。OOPであるかどうかに関係なく、優れた手法は優れています。WINAPIプログラムをCで記述し、自分のコードで同じ手法を使用できるので、CはOOPだと思います。
bruceatk 2008年

3
それはアラン・ケイが考えていたものではないかもしれません(グーグルそれ!)それにもかかわらずOOPです。
Konrad Rudolph、

11

はい、OOPはすべての問題を解決しませんでした。ただし、これらすべての問題を解決するSOAに取り組んでいます。


4
聞こえなかったの?SOAは過去です。今日、私たちの救い主となるのはクラウドコンピューティングです。
DrPizza 2008

あなたの答えが皮肉なものかどうかは本当に疑問です。私は皮肉が好きですが、通常は反対票が投じられるので不思議に思います...
Lena Schimmel

これは皮肉なことだと思うので、反対票を投じません。しかし、私もそれを投票しません!:-)
Yarik、

質問はかなり修辞的であるため、これは有効な回答(および最良の回答)です。
ジェフデイビス

10

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

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

最悪のケースは、OOがデータベースに熱狂的に適用されている場合です。SQLデータベースへの悪質なOOの「拡張機能」も含まれます。これらは、新しいので正しい方法でなければならないと考えるデータベース初心者を除いて、無視されます。


それはすべて本当ですが、おそらく、OOPがアプリケーションの一部のビジネスに関係のない側面(UI実装など)を簡略化できるという事実は、開発者(ついに!)がビジネスにより多くの時間を費やすことができる主な理由の1つにすぎません-関連する側面?
Yarik、

10

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

ビジネスニーズに合うように継承階層を適切に設計することは言うまでもなく、抽象クラスまたはインターフェイスが何であるかを同僚がほとんど知らないのを観察するのはかなり怖いです。

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

もちろん、それは残念ながら非常にまれです。世界の美しく設計された物理オブジェクトと恐ろしく設計された物理オブジェクトの比率と同様に、ソフトウェアエンジニアリングと設計についても同じことが言えます。優れたツールを自由に使えるとは限りません。


1
コードを読んでいる間、私は手続き的に、またはOOPで純粋な喜びフェーズを達成したことはありません。:)
bruceatk

1
純粋な喜び、いや、でもほんの少しの笑顔?
Dan Rosenstark、2008

9

ボンネット、ラップ、ツリーは椅子ではないかもしれませんが、どれもISittableです。


2
インターフェースなしでオブジェクト指向言語を使用する必要はありませんでしたか?幸運ですね。
finnw 2008

いいえ、そうではありません。それらは座っているように設計されていないものなので、私は類推に忠実であると私は思う、ISittableインターフェースを実装するために書かれていなかったでしょう。それらはサードパーティのライブラリからのものであり、座っていることを含むドメインを含むプロジェクトを書いているので、ISittableにするためにそれらをラップするアダプターオブジェクトを書く必要があることに気づきます。見る?現実世界とあまり似ていません。
EricS 14

8

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

あなたがやる?

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

同様にあなたが言及する他のもの。

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


2
あらゆる機械、電子機器、または生物を取り上げてください。それらはすべて「状態と動作の結合」です。
TM。

1
Send()やPay()などのメソッドは、請求書にとって「不自然」であることに同意します。しかし、たとえば、請求書の派生した固有の属性としての合計金額はどうでしょうか?これは、OOPが完全に不活性な実体エンティティに対してさえも、非常に「自然な」方法でモデル化することを可能にするものの例ではありませんか?ない巨大な成果そのものによって、まだ...
Yarik

@Yarik:これらの「不活性」エンティティは、オブジェクトベースの設計につながります。私にとって、唯一の適切なオブジェクト指向はシミュレーションであり、この答えが述べているように、オブジェクトは「独自の動作をすることができます。OOが何かを達成するための扱いやすい方法である場合は問題ありませんが、それ以外の場合は、より単純で解決されている問題のようなものに固執することはできませんか?

7

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

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


7

そもそも、観測はやや乱雑です。ソフトウェアの生産性に関する数字はありませんし、それが上がらないと信じる十分な理由もありません。さらに、オブジェクト指向を乱用する人が多いため、オブジェクト指向をピーナッツバター以来最大のものとしても、オブジェクト指向を上手に使用しても必ずしも生産性が向上するわけではありません。結局のところ、無能な脳外科医は何もないよりも悪い可能性が高いですが、有能な脳外科医は非常に貴重です。

そうは言っても、OOは、手続き型コードをデータに作用させるのではなく、手続き型コードをデータに付加する、別の方法です。OOアプローチの方が自然な場合があるので、これはそれ自体で少なくとも小さな利益になるはずです。結局のところ、C ++で手続き型APIを書くのを妨げるものは何もないので、オブジェクトを提供するオプションを使用することで、言語の用途が広がります。

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

欠点は、優れたオブジェクト指向は無料ではないことです。適切に学習するには時間と労力が必要です。それは大きな流行語であるため、それを行うためだけに、ひどくそれを行う人々や製品はたくさんあります。優れたクラスインターフェイスを設計することは、優れた手続き型APIよりも簡単ではなく、さまざまな種類の簡単なエラー(深いクラス階層など)があります。

それを別の種類のツールと考えてください。必ずしも一般的に優れているとは限りません。たとえば、ドライバーに加えてハンマー。おそらく、ねじを打ち込むためにどのレンチを使用するかを知っているので、最終的にはソフトウェア工学の慣習から抜け出すでしょう。


私はあなたの最後の段落が一番好きです。
Mike Dunlavey、2008

6

@Sean

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

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


6

@Konrad

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

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


6

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

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

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

つまり、私にとってOOPの最も重要な目標は、将来のコードのメンテナンスと変更を容易にすることです。しかし、それを超えても、手続き型コードでは不可能だった方法で正しく実行すると、事態を大幅に簡素化できます。「実世界」と一致していなくても問題ありません。コードを使用したプログラミングは、実世界のオブジェクトとは対話していません。OOPは、私の仕事をより簡単に、より速くするためのツールに過ぎません-私はいつでもそのために行きます。


5

あずきっく

しかし、OOPが時間の浪費であった限り、それは、言語固有のOOPマッピングを学習するという急な学習曲線によって悪化する、プログラマーのトレーニングの欠如が原因であると私は言います。OOPを「取得」する人もいれば、絶対に取得しない人もいます。

でもそれが本当に意外なのなら、私には分からない。技術的に健全なアプローチ(LSPが明らかであること)は使いにくくなると思いますが、そのようなアプローチを使用しないと、コードがもろくなり、拡張できなくなります(理由を説明できないため)。そして、OOPが私たちを導く直観に反する結果は、人々がそれを拾わないことは驚くべきことではないと思います。

さらに重要なことには、ソフトウェアはすでに基本的に人間が信頼して正確に書くには根本的に難しすぎるので、一貫して不十分に教えられ、学ぶのが難しいように見えるテクニックを本当に称賛すべきでしょうか?利点が明確である場合、困難にもかかわらず、それは忍耐する価値があるかもしれませんが、それはそうではないようです。


「適切なトレーニング」は、非常に長く、抽象的かつ複雑である必要があります。私は知っています:私はプログラミングを教えます。数十年前、多くの人が何らかのプログラミングを学ぶことができました。それはもう本当ではないと思います。

5

@ジェフ

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

C ++のiostreamとCのFILE *のどちらがより隠された実装ですか?

2つのよく知られた例を挙げると、不透明なコンテキストオブジェクト(Win32のハンドル、CのFILE * s)の使用が考えられます。それよりもはるかにカプセル化されています)手続き型コードにもあります。これがOOPに特有のものであるかどうかを確認するのに苦労しています。

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


5

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

私は今でも、オブジェクト指向ではないオブジェクト指向に対して、関数を使用したプログラミングはすべてをインラインでプログラミングすることだと信じています。

(そして、私はGWBasicで始めたので、知っておくべきです。)関数を使用するようにコードをリファクタリングするvariable2654variable3、現在のメソッドになります。または、もっとわかりやすいように、名前がわかり、関数が短い場合は、それが呼び出されvalue 、完全に理解するにはそれで十分です。

関数のないコードがメソッドのあるコードになると、何マイルものコードが削除されます。

あなたは本当にOO、するコードをリファクタリングするとbcq、とZなるthisthisthisthis。そして、私はthisキーワードを使用することを信じていないので、あなたはコードのマイルを削除することになります。実際には、あなたが使用していてもそれをやってもらいますthis



OOは自然なメタファーだとは思いません。

言語も自然な比喩だとは思いませんし、ファウラーの「におい」が「このコードはおいしくない」と言うよりも良いとは思いません。とは言っても、オブジェクト指向は自然なメタファーについてのものではなく、オブジェクトがちょうど飛び出てくると考える人は基本的にポイントを逃しています。あなたがオブジェクトの宇宙を定義し、より良いオブジェクトユニバースが理解しやすく、短いコードになり、より良い作品、またはこれらのすべて(およびいくつかの基準は、私は忘れています)。顧客/ドメインの自然なオブジェクトをプログラミングオブジェクトとして使用する人々は、宇宙を再定義する力を欠いていると思います。

たとえば、航空会社の予約システムを使用する場合、予約と呼ばれるものは、法的/ビジネスの予約にまったく対応していない場合があります。



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

たいていの人は、「ハンマーを持っているとき、それらはすべて釘である」ことを誇張していると思います。私は、コイン/ミラーの反対側も同様に真実だと思います。多態性/継承のようなガジェットを持っていると、手袋/靴下/コンタクトレンズのように適合する用途を見つけ始めます。OOのツールは非常に強力です。単一継承は、人々が夢中にならないようにするために絶対に必要であると私は思います。私の独自の多重継承ソフトウェアは耐えられません。



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

非常に大規模なコードベースを処理するのに最適な方法だと思います。コードを整理して再編成し、それを実行するための言語(作業しているプログラミング言語以外)を提供し、コードを非常に自然で理解しやすい方法でモジュール化できると思います。

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

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



あなたのミニエッセイ/質問について

私はあなたが正しいと述べたいと思いました。再利用性は、大部分がパイプドリームです。ここからは、そのトピック(素晴らしい)に関するAnders Hejilsbergからの引用があります

初心者プログラマーにカレンダーコントロールの作成を依頼すると、彼らはよく考えます。そして、マンガー、そしてこれ、あれ、そしてその他。」カレンダーアプリケーションを2か月で出荷する必要があります。彼らはこのすべてのインフラストラクチャを制御下に置き、2日間かけてその上にくだらないカレンダーアプリケーションを作成しました。彼らは、「アプリケーションの次のバージョンでは、もっともっとやるつもりだ」と考えるでしょう。

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


4

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

覚えておきたい以上の回数。

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

次に、それ自体はメッセージディスパッチを行わないこともわかります。また、くだらないサブクラス化もあります。

ハンドルは継承できない可能性がありますが、Javaにはfinalがあります。クラスを欠いているわけではなく、クラスのプレースホルダーです。それが「ハンドル」という言葉の意味です。MFCや.NET WinFormsなどのアーキテクチャを見ると、構文を除いて、WinAPIと何も変わらないことがすぐにわかります。

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

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


Win32インターフェイスは基本的にWin16の再実装であったことを覚えておく必要があります。これは20年以上前に設計されました。
ブラッドギルバート

大学でプログラムすることを学んでいたとき、大部分はCでしたが、他のいくつかの言語でも、いくつかの基本的なアイデアを教えられ、いくつかのプラットフォームに触れましたが、デザイン、フレームワーク、ベストプラクティスを考案する全体的な責任は等は職場で私たち次第です。私たちは世界観ではなく技術を学びました。OOでは、有用なことを行う前に宗教を学ぶ必要があり、それがソリューションの見方を完全に決定します。それは本当に適切だとは思いません。

4

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

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

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


ええ、オブジェクトにはOOP、関数には関数型プログラミングを使用するべきだと思います...
Svante

4

OOPの最も有益な品質は、データの非表示/管理であると思います。しかし、OOPが誤用されている例がたくさんあり、これが混乱を招く場所だと思います。

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

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

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

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

しかしながら。OOPの大きな問題は、すべてがOOPであるべきだと誰かが信じるときです。これは多くの問題を引き起こします。データベースに88のテーブルがあります。クラスは6つしかありませんが、たぶん10つ程度と思います。88クラスは絶対に必要ありません。ほとんどの場合、これらのテーブルに直接アクセスすることは、私が使用する状況では完全に理解できます。OOPを使用すると、発生しているコア機能にアクセスするのが実際には困難または面倒になります。

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


3

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

そして、OOはプログラムを可読にする効果的な方法です。再利用または再利用なし。


2

「現実の世界は「OO」ではない」

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

概念的なもの(実際のウィンドウではなく、Windowsのように、コンピューターモニターのディスプレイパネルなど)のOO設計は、多くの場合、多くのことが望まれます。しかし、請求書、発送注文、保険金請求などの現実世界のものについては、それらの現実世界のものはオブジェクトだと思います。机の上に山積みになっているので、本物でなければなりません。


2

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

このトピックに関する多くの議論に反して、OOPおよびOOの概念は、Cなどの非OOP言語のコードを含むすべてのコード全体に行き渡っています。多くの高度な非OOプログラマーは、非OO言語でもオブジェクトの機能を概算します。

言語にOOが組み込まれているだけで、プログラマーは別の表現方法を利用できます。

コードを書く最大の部分はマシンとの通信ではなく、その部分は簡単で、最大の部分は人間のプログラマーとの通信です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.