web-dev-qa-db-ja.com

オブジェクト指向のものは本当にそれほど重要ですか?

何年もの間、私はアルゴリズム関連の作業を行っており、インターネット検索用のスケーラブルなデータ構造を記述しています。たとえば、自動推奨のためのランダム化バイナリ検索ツリー、ビットマップ、グラフを使用した群集ベースのアルゴリズム、クラスタリング、異常検出などの興味深い機械学習アルゴリズムを書いています。情報検索関連の作業など

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

私はC++が大好きです(-かさばるOOのもの、Erlangの作成者であるジョーアームストロングの発言が気に入っているので、OO世界では、バナナを要求すると、大きなジャングルとゴリラの持ち株が手に入りますバナナ)。 Java、Pythonなどの他の言語でのコーディングも楽しんでいます。

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

簡単に言うと、OOは、上で述べたような種類のプロジェクト/アルゴリズムで私を助けることができますか?

編集:

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

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

8
Yavar

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

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

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

9
Bryan Boettcher

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

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

8
Zachary K

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

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

7
kba

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

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

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

6
dasblinkenlight

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

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

例えば:

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

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

4
Baarn

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

The Next Big Paradigmの強力な候補である関数型プログラミングについて話しますが、FPは業界ではまだ馴染みがありません。特にC++プログラマーである場合、業界はパフォーマンスを重視した保守的なC/C++の世界は、ハードウェアの命令的な性質が非常に現実的な考慮事項と見なされる場所です。一般に、組み込みシステムのプログラマーは、私の経験ではFPに非常に懐疑的です。

FP doesが業界で最も支配的なパラダイムになったとしても、F#やScala "純粋"の形式ではないFP Haskellなどの言語.

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

2
Larry OBrien

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

OOを使用する利点は、プロジェクトのサイズが大きくなるにつれて増加します。1KLOCプログラムの場合、どのパラダイムを使用しても問題ありません。すべてのパラダイムで問題なく動作します。ただし、200KLOC +プログラム、OOの実行可能な競争はありません。だからといって、Cで200KLOCプログラムを書くことができないということではありません。 OOがそのような混乱を防ぐことを意味するのではなく、それがそれを防ぐためにあなたの人生をより簡単にするというだけです。

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

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

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

2
Fabio Ceconello

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

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

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

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

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

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

1
DeadMG

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

Is-aもクラスも継承はもちろん、OOPとは何の関係もないことに注意してください。 OOPが本当に重要なのは、 依存関係の逆転の原理 で定式化されているように、間接的なデカップリングです。)これはFPの重要な側面でもあると主張できます。 OOPおよびFPを使用すると、それらが実際には連続体の両側であることにますます気づくようになります。それをより広く、より深く理解すればするほど、より良いものになります。

OOPを試してみてください Io と、SmalltalkとRubyを試してみてください。

1
back2dos

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

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

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

0
Sam Goldberg