オブジェクト指向のものは本当にそれほど重要ですか?[閉まっている]


8

何年もの間、私はアルゴリズム関連の作業を行っており、インターネット検索用のスケーラブルなデータ構造を作成しています。情報検索関連の作業など

上記で述べたことには共通点があります。上記すべてのもの; C ++のような言語でコーディングされている場合は、それぞれ少数のクラスが必要です。私はそれらが興味深い問題であることを意味しますが、負荷の高いオブジェクト指向のものに関しては複雑ではありません。継承や仮想化などを使用したことがありません。ジェネリックプログラミングやテンプレートなどを頻繁に使用しています。

私はC ++が大好きです(-かさばるOOのもの、Erlangの作成者であるJoe Armstrongの言うところが好きなので、OO Worldではバナナを要求すると、大きなジャングルとバナナを抱えているゴリラができます)。私はJavaやPythonのような他の言語でのコーディングも楽しんでいます。

今私の質問は、私が取り組んでいるプロジェクト/アルゴリズムの種類を楽しんでいるからです。オブジェクト指向の要素を本当に学ぶ必要がありますか。継承、動的ポリモーフィズム(仮想)のようなものを使用するだけで、より優れたコーダー/デザイナーになれますか?または、関数型プログラミングの世界に移動できますか(私は今までそれを行っていません)、タスク/アルゴリズムに集中でき、名詞の王国に基づいたオブジェクト指向の要素、has-a、is-aルールを使用できないので、より魅力的です私?

簡単に言えば、OOは私が上記で言及した種類のプロジェクト/アルゴリズムについて私を助けることができますか?

編集:

ここに追加する1つの非常に興味深いリンク:

http://steve-yegge.blogspot.in/2006/03/execution-in-kingdom-of-nouns.html


25
オブジェクト指向は、今日最も広く使用されているプログラミングパラダイムです。危険にさらされても無視してください。
ロバートハーベイ、

5
<皮肉>いや、心配しないで。Cはあなたのための十分なはずです。</皮肉>。
のOtavioDécio


16
もちろん、OOP / OODは過大評価されています。この簡単なモデルは、限られた一連の問題に対してのみ使用できます。しかし、それを無視するべきではありません。そうしないと、OOPが本当に輝いているまれで狭い領域に間違ったツールを使用してしまうことになります。
SK-logic

13
ライナス・トーバルズ、これはあなたですか?
ジェシーC.スライサー、2012

回答:


9

オブジェクト指向プログラミングは、理解しやすい単語の後ろに複雑な空想的で凝ったものを隠し、自分の中の小人があなたが書いたものを実際に使用することを容易にすることを本当に得意としています。関数型プログラミングに取って代わるものではありません...実装を切り替えたり動作を追加したりするための本当に簡単な方法を提供するだけです。

上記のランダム化されたバイナリ検索ツリーの例で、エイプリルフールの日にランダマイザーをorder-by-distance-from-three-stoogesに置き換えるという要件が与えられた場合はどうなるでしょうか。メソッドを作成StoogeBinaryTree : RandomBinaryTreeしてオーバーライドするのは非常に便利なprotected int GetSortOrder (Tree a, Tree b)ので、4月2日RandomBinaryTreeに、コードを変更せずに実装をに戻すことができます。

簡単な例の1つとして、動作のごく一部を追加することと実装を切り替えることの両方を示しました...


14
これはOOPではありません。まともなモジュールシステムでも同じように(おそらく、はるかに単純な方法で)実行されます。たとえば、SML 1stクラスモジュールを参照してください。
SK-logic

4
@ SK-logic:そして、モジュールとOOPはどのように大きく異なりますか?
DeadMG

12
@DeadMG、適切なモジュールシステムの定義には、状態とメッセージ、および継承に関するBSはありません。カプセル化だけでなく、便利な数学もたくさんあります(この時点で気絶するでしょう)。
SK-logic

2
@ SK-logic:私のOOPシステムはメッセージや継承、過度の状態を使用していません。カプセル化し、必要に応じて、実行時にカプセル化することもできます。もちろん、他の人はやり方が違うかもしれませんが、それは彼らの選択であり、OOPとは関係ありません。
DeadMG

3
@DeadMGでは、オブジェクト指向言語とそうでない言語の違いは何ですか?たとえば、オブジェクト指向に必要なものがすべてモジュールシステムである場合、HaskellやErlangはオブジェクト指向ではありませんか?それとも、それらはオブジェクト指向言語だと言っていますか?
sepp2k

8

HaskellやErlangのようにうまく機能する言語を使用してFPを実行する場合は、OOPのクールエイドを飲む必要はありません。FPは非常に強力で、現実の世界でも多くのことができます

そうは言っても、OOP言語を学ぶことは悪いことではないでしょう。プログラミングの複数の方法といくつかの方法論を理解することは、あなたにとって有利になります。さらに、HaskellまたはErlangからJavaに移行すると、REPLとラムダなしで誰でも世界でどのように作業できるのか疑問に思うはずです。


また、Clojureのような言語はOOPを許可していますが、クラスベースであることに制限していません。つまり、Clojureは、クラスを作成する必要なく(少なくともC#/ Javaがクラスを定義する方法ではなく)、ポリモーフィック関数やインターフェースなどをサポートします。
ティモシーボールドリッジ

Joe Armstrongは、ErlangはC ++やJavaよりもオブジェクト指向の方が多いと主張しています。これらのことについて独断的である必要はありません。リンクをクリックします@ Erlangオブジェクト指向ですか?

ああ、そうではありません、地獄でアーランについての本を書きました(shop.oreilly.com/product/0636920021452.do)が、人々がOOPについて話すとき、アーランは一般的に彼らが意味するものではありません
Zachary K

7

一度に1つの問題を解決することに集中しているようです。つまり、アルゴリズムの作成です。しかし、たとえばGUIアプリケーションや、アルゴリズムの多くを使用する必要がある可能性のある他の巨大なアプリケーションをどのように作成するかを検討してください。その場合、オブジェクトを読み込むことができるライブラリを作成するなど、コードを単純化して他の開発者がより読みやすく簡単に使用できるようにするため、オブジェクト指向を知ることは不可欠です。

オブジェクト指向プログラミングで最も重要な設計パターンの1つは、上記のシナリオでも非常に役立つ戦略パターンです。ユーザーがアルゴリズムの実行を許可する入力をユーザーに提示する例を考えてみます。これは簡単に厄介なif / elseまたはswitch / case構成になる可能性があります。アルゴリズムの共通インターフェースを作成し、Strategy Patternを使用することで、コードははるかに柔軟で読みやすくなり、拡張が容易になり、保守も容易になります。


オブジェクトなしで戦略パターンを非常にエレガントに(もっと論じることができるかもしれませんが)実装する関数型言語について何を言わなければなりませんか?
Steven Evers

4
-1 1)OOPなしでは大規模なアプリケーションは不可能であり、2)ライブラリのロードは何らかの形でOOPに結び付けられていると想定するため。複数のディスパッチ(および式の問題)を読んで、Java / C#/ C ++がプログラマーに不要な制限を課すことにより、多くのタスクを実際に困難にしていることに気付き始めます。
ティモシーボールドリッジ

1
オブジェクトとしてロードできるライブラリが、オブジェクトとしてロードされないライブラリよりも優れていることを教えてください。
aseq 2012

@SnOrfus私がOOを提唱しているのは、それが私が最もよく知っている世界だからです。私は関数型言語の戦略パターンに精通していません
kba

2
「戦略パターン」それは、何よりもOOPについて私を刺激する1つのことです。なぜすべてにパターンが必要なのですか?ビジターパターンのようなものを発明する必要があった唯一の理由は、使用されている言語が非常に制約され複雑で、パターンなしでデータ構造を反復処理することが不可能だったということです。現代のOOP言語のめちゃくちゃな複雑さを取り除き、突然単純な関数としてパターン化します。パターンは、OOPサウンドを作成する方法の1つであり、OOPサウンドを作成する方法の手掛かりになります</ rant>
Timothy Baldridge '29

6

オブジェクト指向のアプローチが成功したのは、1つの重要な側面がありました。偶発的な複雑さを過度に導入することなく、本質的に複雑なシステムに取り組むことができるからです。これは自作のシステムで作業する場合はほとんど無視できますが、大規模なシステムを構築する場合は非常に重要になります。

オブジェクト指向のアプローチの主要な要素は、数日のうちに手続き型プログラミングに多くの経験を持つプログラマーに説明することができます。数日:チェスの学習に似ています。駒を10分以内に移動する方法を学ぶことができますが、ゲームを習得するには何年もかかります)。

関数型プログラミング手法は、主流言語(C#のラムダと匿名デリゲート、C ++のラムダ、さらにはJavaの匿名クラスでさえ)への言語サポートの導入により、ますます重要になっています。これらの手法を理解することは非常に役立ちますが、戦術的なスケールでより局所的な問題に対処するように設計されています。一方、オブジェクト指向の手法は、特に大規模なチームのコンテキストでは、戦略的スケールで関連性を保ちます。


3
複雑さに関して表現された感情には感謝しますが、悲しいことに実際にはその逆です。オブジェクト指向言語には、不必要な肥大化と複雑さを導入するコツがあります。それはしばしば言語のせいではありません。しかし、技術が非常に多くの人々にそれを誤って使用させる傾向があるならば、それはいくらか欠陥があるかもしれないと私は信じます。理論的にはどんなにいい音でも。
aseq 2012

1
dasblinkenlightの+1と私はaseqに同意しません。特に、OOはイベント駆動型GUIを実行するために必要なものに密接に対応していると思います。UIには多くのアクティビティがあるため、OOフレームワークにも多くのアクティビティがあります。OOフレームワークなしでUIを実行すると、実際にはかなり面倒なものを構築してしまいます(X11 Xtを参照)。その本質的な複雑さはまだそこにありますが、フレームワークがなければ、それは恐ろしい方法で突き出します。ジョブに適したツールを使用します。未熟練の開業医が間違ったツールを使用する場合、言語または開業医のせいですか?
Liudvikas Bukys 2012

@aseq「しかし、テクニックが非常に多くの人々にそれを間違って使用させる傾向があるなら、それはいくらか欠陥があるかもしれないと信じています。テクノロジーが異なれば開業医のも異なるため、生の数値を見ると誤解を招きます。パーセンテージはやや意味がありますが、すぐには利用できません。さらに、参入の障壁と非技術的インセンティブの構造により、の異なる施術者が入らないため、割合でも全体像を把握できない場合があります。
dasblinkenlight

1
関数型プログラミングが「戦略的」ではないことはわかりません。それは、どちらかといえば、結合と複雑さを軽減し、より高い抽象化レベルで作業できるようにするため、大規模のOOPよりも優れています。また、純粋に機能的な方法でUIを作成するための非常に優れた手法がいくつかあります。「関数型反応プログラミング」をチェックしてください。
Tikhon Jelvis

4

関数型プログラミングを行うと、続行しないことを決定した場合でも、それはあなたにとって非常に良い経験になります。ここでいくつかの答えを読むことができるので、多くの人はそれが何であるかさえ知りません。

遅延評価や参照の透明性などの関数型言語の概念は、学ぶのにとても良いものです。特に再帰が好きなら。

例えば:

lenth :: [a] -> Integer
length (x:xs) = 1+length(xs)
length [] = 0

リストを再帰して長さを計算する非常に単純なhaskell関数です。long longよりも大きな数値に興味があり、無限リストやその他の凝ったものを使用したい場合は、関数型プログラミングを試してください。


2
これはまた、を実装するための愚かな方法です(事前に構築された抽象化を使用する代わりに手動でトラバースするため、非効率的です)length。別の(より効率的で重要なFPプログラムが実際にどのように記述されているかに近い)方法は、開始値0とステップ関数を使用してフォールドを呼び出すことacc -> acc + 1です。または、sum . map (const 1)うまく読みます。

1
@ジョルジオいいえ、関数は末尾再帰ではありません。そして、それは(1が大サンクを構築避けるために持っている。これもどちらのみ有形efficencyとスタックの使用に関連していますHaskellのような言語では、あってもlength非厳格な上に構築されたfoldのは、これを行います)。

2
@ジョーダン:Haskellでは値を変更できず、すべてのリスト(有限の)長さを持つわけではありません。
ジョンパーディ

3
@ WalterMaier-Murdnelchはい、リストは最終的にたどる必要があり、内部で何が起こるかを理解する必要があります。しかし、それでは抽象化が役に立たなくなるわけではなく、まったく逆になります。SQLクエリ(Yesodを超えてpersistent)、エラー処理(over Maybe/ Either)、状態ジャグリング(over State)、ツリートラバーサル(over Map/ Set)などを記述できますが、高レベルの機能の観点から私の意図を説明することは、ほぼすべての点で優れています、したがってFPも実際に何をするか。

1
@Giorgioまだ標準である厳格な言語では、それはそうです-この最適化を世話するコンパイラーにも依存します(Pythonは、いくつかの都市の神話にもかかわらず、関数型言語ではなく、末尾呼び出しを最適化しません-Lua OTOHはあります)。しかし、非厳密(最も顕著な例:Haskell)になるとすぐに、ルールが変わります。巨大なサンク(怠惰により延期された100万回の積み重ねられた整数の追加)を構築したため、末尾再帰でもスタックオーバーフローが発生する可能性があります。だから私はこのルールを福音とは考えません。

2

他の人が言ったように、オブジェクト指向は業界の主要なパラダイムです。ほんの一握りのクラスで対処できるプログラムを使用して作業してきたとおっしゃいましたが、産業用アプリケーションでは、数百または数千のユースケースに対処する必要があり、オブジェクト指向は非常に信頼できることが証明されていますそして、そのような大きなコードベースを構造化するための広く理解できる方法。

あなたは関数型プログラミングについて話しますが、これはネクストビッグパラダイムの強力な候補ですが、FPはまだ業界に精通していません。特にあなたがC ++プログラマーである場合、業界は保守的であり、パフォーマンスに重点を置いたC / C ++の世界は、ハードウェアの必須の性質が非常に現実的な考慮事項と見なされる場所であることを知っておく必要があります。一般に、組み込みシステムのプログラマーは、私の経験ではFPに非常に懐疑的です。

FP 業界でより有力なパラダイムになったとしても、Haskellのような「純粋な」FP言語の形式ではなく、F#やScalaなどのオブジェクト機能ハイブリッド言語の形式で成功するのは確かです。

つまり、そうです、オブジェクト指向の「もの」は、プロのコードベースとあなたのキャリアにとって重要です。


2

OOは、構造化/手続き型プログラミングもそうであったように、複雑さを処理するための大きな改善であったため、勢いを増しました。

プロジェクトのサイズが大きくなると、OOを使用するメリットが大きくなります。1KLOCプログラムの場合、どのパラダイムを使用してもかまいません。それらはすべて問題なく動作します。しかし、200KLOC +プログラムの場合、OOの競争はありません。これは、Cで200KLOCプログラムを記述できないことを意味するのではなく、誰も(あなたでも)が理解できない混乱に陥らないようにするためには、より多くの規律が必要になるだけです。それはオブジェクト指向がそのような混乱を防ぐという意味ではなく、それがそれを防ぐためにあなたの人生を楽にするでしょう。

関数型プログラミングは、以前のパターンから多少逸脱したパラダイムです。OOの場合よりもさらに複雑な処理には役立ちませんが、並列プログラミングという異なる種類の問題に対処するためです。また、プログラミングパラダイムがこれを試みたのはこれが初めてでした。以前にOOやSP / PPに存在していたすべてのメカニズムは、パラダイムの一部ではなく、OSエンティティ(スレッド、ミューテックスなど)だけでした。パラダイムルールに従ってカプセル化されます。

その点では、FPは他のFPよりもはるかに自然ですが、それは、通常問題について考える方法を逆転させる代償になります。そのため、OOと同じスケールで非常に同じ複雑さを処理する能力は限られています。

私の推測では、これは近い将来にFPの採用を非常に特殊化されたシステム、一般的にそれほど大きくないシステム、またはより大きなシステムの特殊化されたセクションに制限することです。残りは引き続きOOを使用して作成されます。開発を計画している(または開発について学ぶ)もののどれが、学習の焦点、IMOとすべきかを決定します。


1

ジェネリックプログラミング、テンプレートなどを頻繁に使用していますが。

間違いなく、テンプレートは単にOOPの異なる形式です。仮想関数と明示的な継承には、特定のユースケース-ランタイム、バイナリ互換性があります。テンプレートはコンパイル時の互換性です。ただし、最も基本的なレベルでは、正しいインターフェイスを提供するすべてのタイプに対して同じ機能の抽象化を提供します。ランタイム継承の過剰使用はコードの重要な臭いであり、この場合、私はあなたに同意します-それは多くの場合必要とされないだけです。

template<typename T> void func(T t) { t(5); }
void func(std::function<void(int)> t) { t(5); }

1つはテンプレートを使用し、もう1つは実装としてランタイム継承とクラスを使用しますが、これら2つのスニペットは実質的に同一です。どちらも、呼び出す関数を抽象化しています。あなたが代わりとき、これは自明明白であるTためstd::function<void(int)>、たとえば、。唯一の違いは、その抽象化が行われる時間です。テンプレートバージョンは関数に優れており、std::function通常はメンバー変数として使用する方が適しています。新しいコールバックが必要になるたびに新しいクラスを作成する必要はありません。

OOPはアルゴリズムに特に適していません。これは、プログラムの断片を分解する大規模な構成を対象としています。特定のデータを操作する特定のアルゴリズムを記述している場合は、クラスが必要になることはほとんどありません。

関数のアルゴリズムを作成するのは簡単で、すばらしいことです。ただし、それを超えるとすぐに、クラスが主要なメソッドとして浮上します。


9
うわー!テンプレートは「OOPの形式」ですか?あなたは私の一日を作りました、おい!
SK-logic

4
テンプレートはジェネリックプログラミング用です。テンプレートは単にOOPの別の形式であると言うのは正しいとは思いません。Alex Stepanovがこれを読んでいないことを
願ってい

すでに説明したように、2つの関数は事実上同等であり、抽象化も同じです。それは単に別の時に発生します。
DeadMG

4
今日のC ++コミュニティは、以前のOOPの方法で行われた処理にテンプレートメタプログラミングを使用しています。それでも、これを「別の形式のOOP」とは呼びません。特に上の例では、「関数型プログラミングの特殊な形式としてfunctorオブジェクトを使用するC ++の方法」と呼んでいますが、これは典型的なOOPソリューションではありません。
Doc Brown、

4
いくつかの機能は重複しています。それはどちらも便利なため、必然的に両方ともうまくいくことがいくつかあります。しかし、それはそれらが常に同型であることを示しているわけではなく、それらがすべての問題に対して等しく有用であること(たとえば、簡潔で効率的)を示しているわけではありません。純粋に機能的なリンク付きリストは、動的な過剰割り当て配列といくつかの機能も共有します-どちらも順序付けられたコレクションであり、合理的な複雑さで段階的に作成でき、スタックのような使用法(プッシュ/ポップ/ピーク)をサポートしています。しかし、概念的に、実際の多くのアプリケーションで大きく異なります。

1

はい、それは重要です。この1つの理由からです。OOPを理解することで、より優れたプログラマーになることができます。経験則として:理解することは常にあなたをより良いプログラマーにします。

is-aもクラスも継承はもちろん、OOPとは何の関係もないことに注意してください。OOPとは、依存関係の逆転原理によって定式化されているように、間接的なデカップリングです。これはFPの重要な側面でもあると主張することができます。OOPとFPの両方を研究すると、それらが実際には連続体の両面であることをますます認識するようになります。それに対するあなたの理解がより広くそしてより深いほど、あなたはより良くなるでしょう。

OOPを理解するには、Ioや、おそらくSmalltalkとRubyを試してください。


0

開発の世界では、言語はツールであり、プログラミングパラダイムはツールであり、ライブラリはツールです。ツールの数が多いほど、ジョブに適したツールを選択できるようになります。そのため、時間の許す限り、OO、AOP、および関数型プログラミングを学ぶことが求められます。

開発の世界は(言語、フレームワークなどに関して)どんどん大きくなっているので、すべてを学ぶことは期待できません。ただし、これらすべてのイノベーションの目標は、開発者の生産性を高め(開発のスピードと再利用性)、コードをより保守しやすくすることです(理解しやすく、拡張と変更が容易)。

あなたができる最善のことは、ターゲットを絞った継続的な学習を行うことです。あなたが今学んだ新しい何かが、あなたが予期しない方法でより良くより速く何かを完了するのを助けてくれることを願っています。


-1

私はSteve Jobsの本を読んでいて、そこにはXerox PARCラボでSteveがSmallTalkをどのように見たかについての話があります。それは初期のオブジェクト指向言語の1つでした。OOがなければ、グラフィカルユーザーインターフェイス(GUI)のようなものを開発することは恐ろしいことでした。すべての非同期入力により、1つの「オブジェクト」または別の「オブジェクト」での作業中にタスクからタスクへジャンプすることができます。

したがって、関数型言語を使用して多くのことを実行できますが、ユースケースがあります。現実世界の問題とより相互作用するより複雑なシステムを扱い始めると、OOは優れた設計であることがわかります。


最初のMacintosh GUIフレームワーク(Toolbox)は、Win32に比べて正気に見えるCの恐ろしい泥沼でした。OSXに切り替わるまで、OOはMacの世界に入りませんでした。これはひどいアナロジーであり、歴史的にはよくても誤解を招くものです。Wings3DはErlangで記述されており、非常に豊富なGUIを備えており、「実世界」と同じくらい複雑で実用的なユースケースです。

関数型プログラミングがうまく適合しなかった方法を強化します。(私はまだ本を完成していません。彼らがXeroxチームが進めてきた多くの進歩の1つを使用することを選択しなかったのは興味深いことです。Xeroxチームは時代の先を行っているように
思えました

Erlangは関数型言語であり、Wings3Dは非常に高度で複雑なGUIであり、関数型プログラミングは実用的ではなく、OOの方が優れているという主張と矛盾します。関数理論を理解しない限り、そうではありません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.